PluginProbe
Booking Calendar / 11.4.3
Booking Calendar v11.4.3
11.8.3 11.8.2 11.8.1 11.8 11.7 11.6.1 11.6 11.5 11.4.3 11.4.2 11.4.1 11.4 11.3 11.2.1 11.2 11.1 11.0 10.15.7 10.15.6 10.1.3 10.10 10.10.1 10.10.2 10.11 10.11.2 All 203 releases
booking / includes / page-bookings / bookings__sql.php

bookings__sql.php in Booking Calendar 11.4.3, at includes/page-bookings/bookings__sql.php

2,728 lines 119.0 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php /**
2 * @version 1.0
3 * @description Bookings Listing SQL
4 * @category Booking Listing
5 * @author wpdevelop
6 *
7 * @web-site http://oplugins.com/
8 * @email info@oplugins.com
9 *
10 * @modified 2022-04-07
11 * @file ../includes/page-bookings/bookings__sql.php
12 */
13
14 if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
15
16 // <editor-fold defaultstate="collapsed" desc=" D E F A U L T R E Q U E S T " >
17
18 /**
19 * Get params names for escaping and/or default value of such params
20 *
21 * @param string $structure_type 'validate_and_default' (default) | 'validate' | 'default'
22 *
23 * @return array
24 * if $structure_type == '' array ( 'keyword' => array( 'validate' => 's', 'default' => '' )
25 * , 'wh_booking_date' => array( 'validate' => 'digit_or_date', 'default' => '3' ), ...
26 * if $structure_type == 'validate' array ( 'keyword' => 's'
27 * , 'wh_booking_date' => 'digit_or_date'), ...
28 * if $structure_type == 'default' array ( 'keyword' => '' )
29 * , 'wh_booking_date' => '3' ), ...
30 */
31 function wpbc_ajx_get__request_params__names_default( $structure_type = 'validate_and_default' ){
32
33 // Clean specific $_REQUEST params, if param is NOT set then return "default"
34 $params_for_cleaning = array(
35 // 'wh_booking_id' => array( 'validate' => 'digit_or_date', 'default' => '' ),
36
37 // 'digit_or_csd' can check about 'digit_or_csd' in arrays, as well
38 'wh_booking_type' => array( 'validate' => 'digit_or_csd', 'default' => array( '0' ) ) // if ['0'] - All booking resources, ['-1'] - lost bookings in deleted resources
39
40 , 'wh_approved' => array( 'validate' => 'digit_or_csd', 'default' => '' ) // '0' | '1' | ''
41
42 , 'wh_booking_date' => array( 'validate' => 'array', 'default' => array( "3" ) ) // array( "0" ) - Current dates, | array( "3" ) - All dates // number | date 2016-07-20
43 , 'ui_wh_booking_date_radio' => array( 'validate' => 'd', 'default' => 0 ) // '1' | '2' ....
44 , 'ui_wh_booking_date_next' => array( 'validate' => 'd', 'default' => 0 ) // '1' | '2' ....
45 , 'ui_wh_booking_date_prior' => array( 'validate' => 'd', 'default' => 0 ) // '1' | '2' ....
46 , 'ui_wh_booking_date_checkin' => array( 'validate' => 'digit_or_date', 'default' => '' ) // number | date 2016-07-20
47 , 'ui_wh_booking_date_checkout' => array( 'validate' => 'digit_or_date', 'default' => '' ) // number | date 2016-07-20
48
49 , 'wh_what_bookings' => array( 'validate' => array( 'any', 'new', 'imported', 'in_plugin' ), 'default' => 'any' ) // '1' | ''
50
51 , 'wh_modification_date' => array( 'validate' => 'array', 'default' => array( "3" ) ) // number | date 2016-07-20
52 , 'ui_wh_modification_date_radio' => array( 'validate' => 'd', 'default' => 0 ) // '1' | '2' ....
53 , 'ui_wh_modification_date_prior' => array( 'validate' => 'd', 'default' => 0 ) // '1' | '2' ....
54 , 'ui_wh_modification_date_checkin' => array( 'validate' => 'digit_or_date', 'default' => '' ) // number | date 2016-07-20
55 , 'ui_wh_modification_date_checkout' => array( 'validate' => 'digit_or_date', 'default' => '' ) // number | date 2016-07-20
56
57 , 'keyword' => array( 'validate' => 's', 'default' => '' ) //string
58
59 , 'wh_pay_status' => array( 'validate' => 'array', 'default' => array( 'all' ) )
60 , 'ui_wh_pay_status_radio' => array( 'validate' => 's', 'default' => '' ) // string
61 , 'ui_wh_pay_status_custom' => array( 'validate' => 's', 'default' => '' ) // string
62
63 , 'wh_cost' => array( 'validate' => 'float_or_empty', 'default' => '' ) // '1' | ''
64 , 'wh_cost2' => array( 'validate' => 'float_or_empty', 'default' => '' ) // '1' | ''
65
66 , 'wh_sort' => array( 'validate' => array(
67 'booking_id__asc',
68 'booking_id__desc',
69 'dates__asc',
70 'dates__desc',
71 'resource__asc',
72 'resource__desc',
73 'cost__asc',
74 'cost__desc'
75 ), 'default' => 'booking_id__desc' )
76 , 'wh_trash' => array( 'validate' => array( '0', 'trash', 'any' ), 'default' => 'any' )
77
78 , 'page_num' => array( 'validate' => 'd', 'default' => 1 ) // '1' | ''
79 , 'page_items_count' => array( 'validate' => 'd', 'default' => 10 ) // '1' | ''
80
81 , 'ui_usr__send_emails' => array( 'validate' => array( 'send', 'not_send' ), 'default' => 'send' )
82 , 'ui_usr__is_expand_remarks' => array( 'validate' => array( 'On', 'Off' ), 'default' => 'Off' )
83 , 'ui_usr__default_selected_toolbar' => array( 'validate' => array( 'filters', 'actions', 'options' ), 'default' => 'filters' )
84
85 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
86 , 'ui_reset' => array( 'validate' => 's', 'default' => '' ) // string
87 , 'ui_usr__dates_short_wide' => array( 'validate' => array( 'short', 'wide' ), 'default' => 'short' )
88 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
89 , 'view_days_num' => array( 'validate' => 'd', 'default' => 30 ) // '1' | '' // FixIn: 8.9.2.1.
90 , 'scroll_start_date' => array( 'validate' => 'digit_or_date', 'default' => '' ) // number | date 2016-07-20
91 , 'scroll_day' => array( 'validate' => 'd', 'default' => 0 ) // '1' | ''
92 , 'scroll_month' => array( 'validate' => 'd', 'default' => 0 ) // '1' | ''
93 , 'limit_hours' => array( 'validate' => 'digit_or_csd', 'default' => '' ) //
94 , 'only_booked_resources' => array( 'validate' => 'd', 'default' => 0 ) // '1' | ''
95
96 );
97
98 if ( 'validate_and_default' == $structure_type ) {
99 return $params_for_cleaning;
100 }
101
102 $return_simple_arr = array();
103
104 foreach ( $params_for_cleaning as $key => $value ) {
105 $return_simple_arr[ $key ] = $value[ $structure_type ];
106 }
107 return $return_simple_arr;
108 }
109
110 // </editor-fold>
111
112
113 // <editor-fold defaultstate="collapsed" desc=" S A V E U S E R R E Q U E S T " >
114
115 /**
116 * Save user filter request - saving user filters in toolbar
117 *
118 * @param array $params
119 * @param integer $user_id
120 *
121 * @return bool|int
122 */
123 function wpbc_ajx__user_request_params__save( $params, $user_id ) {
124
125 // Reset some parameters, like selected page
126 if ( isset( $params['page_num'] ) ) {
127 $params['page_num'] = 1;
128 $params['keyword'] = '';
129 }
130
131 return update_user_option( (int) $user_id, 'booking_listing_request_params' , $params );
132 }
133
134 /**
135 * Delete saved user request - used for resetting user filters in toolbar
136 * @param integer $user_id
137 *
138 * @return bool
139 */
140 function wpbc_ajx__user_request_params__delete( $user_id ) {
141
142 if ( empty( $user_id ) ) {
143 $user_id = wpbc_get_current_user_id();
144 }
145
146 return delete_user_option( (int) $user_id, 'booking_listing_request_params' );
147 }
148
149 /**
150 * Get saved user filter request - params for user filters in toolbar
151 *
152 * @param integer $user_id
153 *
154 * @return false|mixed
155 */
156 function wpbc_ajx__user_request_params__get( $user_id ) {
157
158 if ( empty( $user_id ) ) {
159 $user_id = wpbc_get_current_user_id();
160 }
161
162 // wpbc_ajx__user_request_params__delete($user_id); //For debugging. delete it.
163
164 return get_user_option( 'booking_listing_request_params', (int) $user_id );
165 }
166
167 /**
168 * Get sanitized array of use request parameters that was saved before
169 *
170 * @param $user_id int
171 *
172 * @return array|false
173 */
174 function wpbc_ajx__user_request_params__get_sanitized( $user_id ) {
175
176 $request_params_values_arr = wpbc_ajx__user_request_params__get( $user_id ); // - $request_params_values_arr - unserialized here automatically
177
178 if ( false !== $request_params_values_arr ) {
179
180 $request_params_structure = wpbc_ajx_get__request_params__names_default(); /**
181 * array( 'page_num' => array( 'validate' => 'd', 'default' => 1 )
182 * , 'page_items_count' => array( 'validate' => 'd', 'default' => 10 )
183 * , 'sort' => array( 'validate' => array( 'booking_id' ), 'default' => 'booking_id' )
184 * , 'sort_type' => array( 'validate' => array( 'ASC', 'DESC'),'default' => 'DESC' )
185 * , 'keyword' => array( 'validate' => 's', 'default' => '' )
186 * , 'create_date' => array( 'validate' => 'date', 'default' => '' )
187 * )
188 */
189
190 $escaped_request_params = wpbc_sanitize_params_in_arr( $request_params_values_arr, $request_params_structure ); // Escaping params here
191
192
193 return $escaped_request_params;
194 } else {
195 return false;
196 }
197 }
198
199 /**
200 * Get user saved option from Request in Booking Listing
201 *
202 * @param $user_id int 1
203 * @param $option_name string 'ui_usr__send_emails'
204 *
205 * @return false|mixed
206 */
207 function wpbc_ajx__user_request_params__get_option( $user_id, $option_name ){
208
209 // Get User saved option from request
210 $escaped_request_params = wpbc_ajx__user_request_params__get_sanitized( $user_id );
211 if ( ( ! empty( $escaped_request_params ) ) && ( ! empty( $escaped_request_params[ $option_name ] ) ) ) {
212 return $escaped_request_params[ $option_name ];
213 }
214
215 // Get default option
216 $default_param_values = wpbc_ajx_get__request_params__names_default( 'default' );
217 if ( ! empty( $default_param_values[ $option_name ] ) ) {
218 return $default_param_values[ $option_name ];
219 }
220
221 // There is no such option
222 return false;
223 }
224
225
226 /**
227 * Is send emails ? Check DB SAVED user defined option from Options toolbar.
228 * @param $user_id int ID of user
229 *
230 * @return int 1 | 0
231 */
232 function wpbc_ajx__user_request_option__is_send_emails( $user_id ){
233
234 $is_send_emeils = wpbc_ajx__user_request_params__get_option( $user_id, 'ui_usr__send_emails' );
235
236 $is_send_emeils = ( 'send' == $is_send_emeils ) ? 1 : 0;
237
238 return $is_send_emeils;
239 }
240
241 /**
242 * Is expand remarks by default ? Check DB SAVED user defined option from Options toolbar.
243 *
244 * It's useful only, when we are checking during Ajax action requests, where need to check data in Database,
245 * For templates, need to use JavaScript:
246 * <# if ( 'Off' === wpbc_ajx_booking_listing.search_get_param('ui_usr__is_expand_remarks') ) { #>display: none;<# } #>
247 *
248 *
249 * @param $user_id int ID of user
250 *
251 * @return int 1 | 0
252 */
253 function wpbc_ajx__user_request_option__is_expand_remarks( $user_id ){
254
255 $is_send_emeils = wpbc_ajx__user_request_params__get_option( $user_id, 'ui_usr__is_expand_remarks' );
256
257 $is_send_emeils = ( 'On' == $is_send_emeils ) ? 1 : 0;
258
259 return $is_send_emeils;
260 }
261
262
263 // </editor-fold>
264
265
266 // <editor-fold defaultstate="collapsed" desc=" S Q L " >
267
268
269 /**
270 * Get array of bookings and total number of items in all pages.
271 *
272 * @param array $request_params = Array(
273 [wh_booking_id] =>
274 [wh_booking_type] =>
275 [booking_type] =>
276 [wh_approved] =>
277 [wh_booking_date] =>
278 [wh_booking_date2] =>
279 [wh_booking_datenext] => 0
280 [wh_booking_dateprior] => 0
281 [wh_booking_datefixeddates] =>
282 [wh_booking_date2fixeddates] =>
283 [wh_is_new] => 0
284 [wh_modification_date] =>
285 [wh_modification_date2] =>
286 [wh_modification_dateprior] => 0
287 [wh_modification_datefixeddates] =>
288 [wh_modification_date2fixeddates] =>
289 [wh_pay_statuscustom] =>
290 [wh_pay_status] =>
291 [wh_cost] => 0
292 [wh_cost2] => 0
293 [wh_sort] =>
294 [wh_trash] =>
295 [page_num] => 1
296 [page_items_count] => 10
297 [view_days_num] => 30
298 [scroll_start_date] =>
299 [scroll_day] => 0
300 [scroll_month] => 0
301 [limit_hours] =>
302 [only_booked_resources] => 0
303 )
304 *
305 * @return array = Array(
306 [count] => 14
307 [data_arr] => Array (
308 [0] => Array (
309 [ajx_booking_id] => 14
310 [last_check_booking_id] => 0
311 [status] =>
312 [last_run_date] =>
313 [booking] => Array (
314 [email_template] => super_new
315 [conditions] => Array (
316 [0] => Array (
317 [if] => __system__|source
318 [sign] => >=
319 [value] => 1"0'0\0
320 )
321 ), ...
322 )
323 [ru_create_date] => 2020-01-25 10:36:55
324 ...
325 ), ...
326 */
327 function wpbc_ajx_get_booking_data_arr( $request_params ){
328
329 // 1. Get booking resources (sql)
330 $resources_arr = wpbc_ajx_get_all_booking_resources_arr(); /**
331 * Array ( [0] => Array ( [booking_type_id] => 1
332 [title] => Standard
333 [users] => 1
334 [import] =>
335 [export] =>
336 [cost] => 25
337 [default_form] => standard
338 [prioritet] => 0
339 [parent] => 0
340 [visitors] => 2
341 ), ... */
342
343 $resources_arr_sorted = wpbc_ajx_get_sorted_booking_resources_arr( $resources_arr );
344
345 // 2. Get all bookings (sql)
346 $bookings = wpbc_ajx_get__bookings_obj__sql( $request_params ); /**
347 * Array ( [count] => 172, [bookings] => Array (
348 * [0] => stdClass Object (
349 [booking_id] => 175
350 [trash] => 0
351 [sync_gid] =>
352 [is_new] => 1
353 [status] =>
354 [sort_date] => 2022-04-19 12:00:01
355 [modification_date] => 2022-04-03 08:05:13
356 [form] => selectbox-one^rangetime5^12:00 - 14:00~text^name5^test data~ ... ~checkbox^term_and_condition5[]^I Accept terms
357 [hash] => ae964965356f7c735139764eebe12a63
358 [booking_type] => 5
359 [remark] =>
360 [cost] => 50.00
361 [pay_status] => 164896951360.82
362 [pay_request] => 0
363 ), ....
364 */
365 $bookings_obj = $bookings['bookings'];
366 $bookings_count = $bookings['count'];
367
368
369 // 3. Get booking dates (sql)
370 $booking_dates_obj = wpbc_ajx_get__booking_dates_obj__sql( $bookings_obj ); /**
371 * Array ( [0] => stdClass Object (
372 [booking_dates_id] => 333
373 [booking_id] => 165
374 [booking_date] => 2022-03-28 11:00:01
375 [approved] => 0
376 [type_id] =>
377 )
378 [1] => ....
379 */
380
381
382 // 4. Include dates into bookings (Wide and Short dates view)
383 $bookings_with_dates = wpbc_ajx_include_bookingdates_in_the_bookings( $bookings_obj, $booking_dates_obj );
384 /**
385 Array ( [182] => stdClass Object (
386
387 [booking_db] => stdClass Object (
388 [booking_id] => 182
389 [trash] => 0
390 [sync_gid] =>
391 [is_new] => 1
392 [status] =>
393 [sort_date] => 2023-01-23 10:00:01
394 [modification_date] => 2022-04-18 12:23:30
395 [form] => selectbox-one^rangetime2^10:00 - 12:00~text^name2^rr~text^secondname2^hjk~email^email2^hyui@nbco.csdf~text^phone2^h~text^address2^khj~text^city2^e~text^postcode2^hj~selectbox-one^country2^HT~selectbox-one^visitors2^1~selectbox-one^children2^0~textarea^details2^djkh~checkbox^term_and_condition2[]^I Accept term and conditions
396 [hash] => a1ae510d8fee961b7f8ae53101632151
397 [booking_type] => 2
398 [remark] =>
399 [cost] => 75.00
400 [pay_status] => 165028101080.84
401 [pay_request] => 0
402 )
403 [id] => 182
404 [approved] => 0
405 [dates] => Array (
406 [0] => 2023-01-23 10:00:01
407 [1] => 2023-01-25 00:00:00
408 [2] => 2023-01-27 12:00:02
409 )
410 [child_id] => Array (
411 [0] =>
412 [1] =>
413 [2] =>
414 )
415 [short_dates] => Array (
416 [0] => 2023-01-23 10:00:01
417 [1] => ,
418 [2] => 2023-01-25 00:00:00
419 [3] => ,
420 [4] => 2023-01-27 12:00:02
421 )
422 [short_dates_child_id] => Array (
423 [0] =>
424 [1] =>
425 [2] =>
426 [3] =>
427 [4] =>
428 )
429 )
430 [181] => stdClass Object ...
431 */
432
433 // 4.5 remove some bookings, that does not fit to Dates conditions
434 list( $bookings_with_dates, $bookings_count ) = wpbc_ajx_get__remove_bookings__where_dates_outside( $request_params, $bookings_with_dates, $bookings_count );
435
436 // 5. Parse forms
437 $parsed_bookings = wpbc_ajx_parse_bookings( $bookings_with_dates, $resources_arr );
438 /** array( [188] => stdClass Object (
439 [booking_db] => stdClass Object (
440 [booking_id] => 188
441 [trash] => 0
442 [sync_gid] =>
443 [is_new] => 1
444 [status] =>
445 [sort_date] => 2023-03-05 10:00:01
446 [modification_date] => 2022-04-19 11:58:31
447 [form] => text^selected_short_dates_hint4^March 5, 2023~text^days_number_hint4^1~text^cost_hint4^&amp;#36;95~selectbox-one^rangetime4^10:00 - 12:00~text^name4^test~email^email4^test@wpbookingcalendar.com~selectbox-one^my_select4^1~selectbox-multiple^multi_select4[]^0,1,2,3~checkbox^my_checkbx4[]^false~checkbox^my_multi_checkbx4[]^1~checkbox^my_multi_checkbx4[]^~checkbox^my_multi_checkbx4[]^3~checkbox^exclusive_multi_checkbx4^~checkbox^exclusive_multi_checkbx4^2~checkbox^exclusive_multi_checkbx4^~radio^my_radio4^2~selectbox-one^country4^GB~textarea^details4^s~checkbox^term_and_condition4[]^I Accept term and conditions
448 [hash] => dd12c3a61f14aaca693f52d110d2723a
449 [booking_type] => 4
450 [remark] =>
451 [cost] => 95.00
452 [pay_status] => 165036591118.88
453 [pay_request] => 0 )
454 [id] => 188
455 [approved] => 0
456 [dates] => Array ( [0] => 2023-03-05 10:00:01 [1] => 2023-03-05 12:00:02 )
457 [child_id] => Array([0] => [1] => )
458 [short_dates] => Array ( [0] => 2023-03-05 10:00:01 [1] => - [2] => 2023-03-05 12:00:02 )
459 [short_dates_child_id] => Array ( [0] => [1] => [2] => )
460 [form_data] => Array
461 (
462 [selected_short_dates_hint] => March 5, 2023
463 [days_number_hint] => 1
464 [cost_hint] => &amp;#36;95
465 [rangetime] => 10:00 AM - 12:00 PM
466 [name] => test
467 ...
468 [term_and_condition] => I Accept term and conditions
469 [booking_id] => 188
470 [trash] => 0
471 [sync_gid] =>
472 [is_new] => 1
473 [status] =>
474 [sort_date] => 2023-03-05 10:00:01
475 [modification_date] => 2022-04-19 11:58:31
476 [hash] => dd12c3a61f14aaca693f52d110d2723a
477 [booking_type] => 4
478 [cost] => 95.00
479 [pay_status] => 165036591118.88
480 [pay_request] => 0
481 [id] => 188
482 [approved] => 0
483 [resource_title] => Apartment#3
484 [_form_show] => "<div class="payment-content-form"><strong>Times</strong>:<span class="fieldvalue">10:00 AM - 12:00 PM</span>&nbsp;&nbsp; ...."
485 )
486 ...
487 */
488
489 // Reset array keys for correct DESC sorting during sending Ajax request.
490 $parsed_bookings = array_values( $parsed_bookings );
491
492 return array(
493 'booking_resources' => $resources_arr_sorted, //$resources_arr,
494 'data_arr' => $parsed_bookings,
495 'count' => $bookings_count
496 );
497 }
498
499 /**
500 * R E S O U R C E S - Get SORTED booking resources as array
501 *
502 * @param $resources_arr array Array ( [1] => Array (
503 [booking_type_id] => 1
504 [title] => Standard
505 [users] => 1
506 [import] =>
507 [export] =>
508 [cost] => 25
509 [default_form] => standard
510 [prioritet] => 0
511 [parent] => 0
512 [visitors] => 2
513 ), ...
514 *
515 * @return array
516 */
517 function wpbc_ajx_get_sorted_booking_resources_arr( $resources_arr ) {
518
519 if ( ! empty( $resources_arr ) ) {
520 $resources_arr_sorted = wpbc_ajx_arrange_booking_resources_arr( $resources_arr );
521 $resources_arr_sorted = $resources_arr_sorted['linear_resources'];
522 foreach ( $resources_arr_sorted as $key_id => $resource ) {
523 $resources_arr_sorted[ $key_id ]['title'] = wpbc_lang( $resources_arr_sorted[ $key_id ]['title'] );
524 }
525 // Reset keys for having correct sorting (important for parent/child resources) after ajax response
526 $resources_arr_sorted = array_values( $resources_arr_sorted );
527 } else {
528 $resources_arr_sorted = $resources_arr;
529 }
530
531 return $resources_arr_sorted;
532 }
533
534
535 /**
536 * R E S O U R C E S - Get all booking resources as array
537 *
538 * @return array Array ( [1] => Array (
539 [booking_type_id] => 1
540 [title] => Standard
541 [users] => 1
542 [import] =>
543 [export] =>
544 [cost] => 25
545 [default_form] => standard
546 [prioritet] => 0
547 [parent] => 0
548 [visitors] => 2
549 ), ...
550 */
551 function wpbc_ajx_get_all_booking_resources_arr( ){
552
553 if ( ! class_exists( 'wpdev_bk_personal' ) ) {
554 return array();
555 }
556
557 $db_names = wpbc_get_db_names();
558
559 $sql = array();
560
561 $sql['select'] = "SELECT * FROM {$db_names['resources']} as bt";
562
563 $sql['where'] = " WHERE ( 1 = 1 )";
564
565 if ( class_exists( 'wpdev_bk_multiuser' ) ) { // MultiUser - only specific booking resources for specific Regular User in Admin panel.
566
567 // phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.NonceVerification.Missing
568 if ( isset( $_REQUEST['wpbc_ajx_user_id'] ) ) {
569 $user_bk_id = intval( $_REQUEST['wpbc_ajx_user_id'] ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.NonceVerification.Missing
570 } else {
571 $user_bk_id = wpbc_get_current_user_id();
572 }
573 $is_user_super_admin = apply_bk_filter( 'is_user_super_admin', $user_bk_id );
574
575 if ( ! $is_user_super_admin ) {
576 $sql['where'] .= 'AND users = ' . $user_bk_id . ' ';
577 }
578 }
579
580 // Order depends from version // FixIn: 9.9.0.23.
581 if ( class_exists( 'wpdev_bk_biz_l' ) ) {
582 $sql['order'] = " ORDER BY parent, prioritet, title, booking_type_id";
583 } else {
584 $sql['order'] = " ORDER BY title, booking_type_id";
585 }
586
587 global $wpdb;
588 $sql_prepared = //$wpdb->prepare(
589 $sql['select']
590 . $sql['where']
591 . $sql['order'];
592 // , $sql['sql_args']
593 // );
594 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.NotPrepared, PluginCheck.Security.DirectDB.UnescapedDBParameter
595 $resources = $wpdb->get_results( $sql_prepared );
596
597 $resources_arr = array();
598
599 foreach ( $resources as $resource ) {
600 $resources_arr[ $resource->booking_type_id ] = get_object_vars( $resource );
601 }
602
603 return $resources_arr;
604 }
605
606
607 /**
608 * Get arranged / sorted booking resources arrays
609 *
610 * @param $resources_sql_arr array( ...
611 * [4] => Array (
612 [booking_type_id] => 4
613 [title] => Apartment#3
614 [users] => 1
615 [import] =>
616 [export] =>
617 [cost] => 270
618 [default_form] => standard
619 [prioritet] => 1
620 [parent] => 0
621 [visitors] => 1
622 )
623 [5] => Array (
624 [booking_type_id] => 5
625 [title] => Standard-1
626 [users] => 1
627 [import] =>
628 [export] =>
629 [cost] => 25
630 [default_form] => standard
631 [prioritet] => 1
632 [parent] => 1
633 [visitors] => 1
634 )
635 ...
636 */
637 function wpbc_ajx_arrange_booking_resources_arr( $all_resources ){
638
639 if ( count( $all_resources ) > 0 ) {
640
641 $resources = array();
642 $child_resources = array();
643 $parent_single_resources = array();
644
645 foreach ( $all_resources as $single_resources ) {
646
647 $single_resources = $single_resources ;
648 $single_resources['id'] = $single_resources['booking_type_id'];
649
650 // Child booking resource
651 if ( ( ! empty( $single_resources[ 'parent' ] ) )
652 ){ // Child
653
654 if ( ! isset( $child_resources[ $single_resources['parent'] ] ) )
655 $child_resources[ $single_resources['parent'] ] = array();
656
657 $child_resources[ $single_resources['parent'] ][ $single_resources['id'] ] = $single_resources;
658
659 } else { // Parent or Single
660
661 $parent_single_resources[ $single_resources['id'] ] = $single_resources;
662 }
663 // All resources
664 $resources[ $single_resources['id'] ] = $single_resources;
665 }
666
667
668 $final_resource_array = array();
669 foreach ( $parent_single_resources as $key => $res) {
670
671 // Calc Capacity
672 if ( isset( $child_resources[$res['id']] ) ) $res['count'] = count( $child_resources[$res['id']] ) + 1;
673 else $res['count'] = 1;
674
675 // Fill the parent resource
676 $final_resource_array[ $res['id'] ] = $res;
677
678 // Fill all child resources (its already sorted) - for having linear array with child resourecs.
679 if ( isset( $child_resources[ $res['id'] ] ) ) {
680 foreach ( $child_resources[ $res['id'] ] as $child_obj ) {
681 $child_obj['count'] = 1;
682 $final_resource_array[ $child_obj['id'] ] = $child_obj;
683 }
684 }
685 }
686
687 return array(
688 'linear_resources' => $final_resource_array
689 , 'single_or_parent' => $parent_single_resources
690 , 'child' => $child_resources
691 );
692 } else {
693 return false;
694 }
695 }
696
697
698 /**
699 * S Q L - B O O K I N G S - Get array of "Bookings" objects from DB
700 * based on request params
701 *
702 * @param array $request_params
703 *
704 * @return array of bookings sql objects
705 */
706 function wpbc_ajx_get__bookings_obj__sql( $request_params ) {
707
708 $defaults = wpbc_ajx_get__request_params__names_default( 'default' );
709
710 $params = wp_parse_args( $request_params, $defaults );
711
712 global $wpdb;
713 $db_names = wpbc_get_db_names();
714
715 $sql_args = array();
716 $sql = array();
717
718
719 $sql['start_select'] = " SELECT * ";
720 $sql['start_count'] = " SELECT COUNT(*) as count";
721 $sql['from'] = " FROM {$db_names['bookings']} as bk";
722
723 $sql['where'] = " WHERE ( 1 = 1 )";
724
725 ////////////////////////////////////////////////////////////////////////////////////////////////////////////
726 // DATES
727 ////////////////////////////////////////////////////////////////////////////////////////////////////////////
728 $sql['where'] .= " AND ( EXISTS (
729 SELECT *
730 FROM {$db_names['dates']} as dt
731 WHERE bk.booking_id = dt.booking_id ";
732
733 // W H E R E : Approved | Pending ----------------------------------------------------------------------
734 if ( $request_params['wh_approved'] !== '' ) {
735 $sql['where'] .= " AND approved = {$request_params['wh_approved']} ";
736 }
737
738 // W H E R E : D A T E S --------------------------------------------------------------------------------
739 if (1){
740 if ( is_array( $request_params['wh_booking_date'] ) ) {
741 $wh_booking_date = array_replace( array( '', '' ), $request_params['wh_booking_date'] ); // Always have minimum 2 values in arr
742 } else {
743 $wh_booking_date = array( '', '' );
744 }
745
746 if ( count( $wh_booking_date ) > 2 ) {
747 $removed_el = array_shift( $wh_booking_date ); // Remove an element off the beginning of array
748 }
749 }
750 $sql['where'] .= wpbc_ajx__sql_where_for_dates( (string) $wh_booking_date[0], (string) $wh_booking_date[1] );
751
752 $sql['where'] .= " )
753 )";
754 ////////////////////////////////////////////////////////////////////////////////////////////////////////////
755
756
757 // W H E R E : M o d i f i c a t i o n D A T E S --------------------------------------------------
758 if (1){
759 if ( is_array( $request_params['wh_modification_date'] ) ) {
760 $wh_modification_date = array_replace( array( '', '' ), $request_params['wh_modification_date'] ); // Always have minimum 2 values in arr
761 } else {
762 $wh_modification_date = array( '', '' );
763 }
764
765 if ( count( $wh_modification_date ) > 2 ) {
766 $removed_el = array_shift( $wh_modification_date ); // Remove an element off the beginning of array
767 }
768 }
769 $sql['where'] .= wpbc_ajx__sql_where_for_modification_date( (string) $wh_modification_date[0], (string) $wh_modification_date[1] );
770
771
772
773 // W H E R E : Resources ------------------------------------------------------------------------------
774 if ( class_exists( 'wpdev_bk_personal' ) ) {
775
776 if ( ! empty( $request_params['wh_booking_type'] ) ) {
777
778 $sql['where'] .= wpbc_ajx__sql_where_for_resources(
779 $request_params['wh_booking_type'],
780 $request_params['wh_approved'],
781 (string) $wh_booking_date[0],
782 (string) $wh_booking_date[1]
783 );
784 }
785 }
786
787
788 // W H E R E : Payment Status -------------------------------------------------------------------------
789 if ( class_exists( 'wpdev_bk_biz_s' ) ) {
790
791 if ( ! empty( $request_params['wh_pay_status'] ) ) {
792
793 $sql_and_args = wpbc_ajx__sql_where_for_payment_status( $request_params['wh_pay_status'] );
794
795 $sql['where'] .= $sql_and_args[0];
796
797 if ( count( $sql_and_args[1] ) > 0 ) {
798 foreach ( $sql_and_args[1] as $my_arg ) {
799 $sql_args[] = $my_arg;
800 }
801 }
802
803 }
804 }
805
806
807 // W H E R E : C o s t Min - Max -------------------------------------------------------------------
808 if ( class_exists( 'wpdev_bk_biz_s' ) ) {
809
810 if ( ( isset( $request_params['wh_cost'] ) )
811 || ( isset( $request_params['wh_cost2'] ) ) ) {
812
813 $wh_cost_min = ( isset( $request_params['wh_cost'] ) ) ? $request_params['wh_cost'] : '';
814 $wh_cost_max = ( isset( $request_params['wh_cost2'] ) ) ? $request_params['wh_cost2'] : '';
815
816 $sql_and_args = wpbc_ajx__sql_where_cost_min_max( $wh_cost_min, $wh_cost_max );
817
818 $sql['where'] .= $sql_and_args[0];
819
820 if ( count( $sql_and_args[1] ) > 0 ) {
821 foreach ( $sql_and_args[1] as $my_arg ) {
822 $sql_args[] = $my_arg;
823 }
824 }
825
826 }
827 }
828
829
830
831 // W H E R E : Trash -----------------------------------------------------------------------------------
832 if ( isset( $request_params['wh_trash'] ) ) {
833
834 if ( '0' === $request_params['wh_trash'] ) { // Existing
835 $sql['where'] .= " AND bk.trash = 0 ";
836 }
837
838 if ( 'trash' === $request_params['wh_trash'] ) { // In trash
839 $sql['where'] .= " AND bk.trash = 1 ";
840 }
841
842 //if ( 'any' === $request_params['wh_trash'] ) { } // Any
843 }
844
845
846 // W H E R E : All bookings | New bookings | Imported bookings | Plugin bookings
847 if ( isset( $request_params['wh_what_bookings'] ) ) {
848
849 if ( 'any' === $request_params['wh_what_bookings'] ) {
850 //$sql['where'] .= " AND bk.is_new = 0 ";
851 }
852 if ( 'new' === $request_params['wh_what_bookings'] ) {
853 $sql['where'] .= " AND bk.is_new = 1";
854 }
855 if ( 'imported' === $request_params['wh_what_bookings'] ) {
856 $sql['where'] .= " AND bk.sync_gid != '' ";
857 }
858 if ( 'in_plugin' === $request_params['wh_what_bookings'] ) {
859 $sql['where'] .= " AND bk.sync_gid = '' ";
860 }
861 }
862
863
864 // W H E R E : K E Y W O R D
865 if ( ! empty( $params['keyword'] ) ) {
866 $sql['where'] .= " AND ( ";
867
868 /**
869 * Relative configuration of LIKE sanitization
870 * check at the bottom here https://code.tutsplus.com/articles/data-sanitization-and-validation-with-wordpress--wp-25536
871 *
872 * So this is a correct way:
873 *
874 * $sql['where'] .= "( bk.form LIKE %s ) ";
875 * $sql_args[] = '%' . $wpdb->esc_like( $params['keyword'] ) . '%';
876 *
877 */
878
879 $sql['where'] .= "( bk.form LIKE %s ) ";
880 $sql_args[] = '%' . $wpdb->esc_like( $params['keyword'] ) . '%';
881
882 if ( is_numeric( $params['keyword'] ) ) {
883 $sql['where'] .= " OR ( bk.booking_id = %d ) ";
884 $sql_args[] = intval( $params['keyword'] );
885 }
886
887 $sql['where'] .= " OR ( bk.sync_gid LIKE %s ) ";
888 $sql_args[] = '%' . $wpdb->esc_like( $params['keyword'] ) . '%';
889
890 if ( class_exists( 'wpdev_bk_personal' ) ) {
891 $sql['where'] .= " OR ( bk.remark LIKE %s ) ";
892 $sql_args[] = '%' . $wpdb->esc_like( $params['keyword'] ) . '%';
893
894 $sql['where'] .= " OR ( bk.hash LIKE %s ) ";
895 $sql_args[] = '%' . $wpdb->esc_like( $params['keyword'] ) . '%';
896 }
897
898 $sql['where'] .= " )";
899
900
901 // W H E R E : booking ID // FixIn: 9.4.3.9.
902 $is_id = strpos( trim( strtolower( $params['keyword'] ) ) , 'id:' ); // Keyword, like 'id:200' OR 'id:100,105'
903 if ( 0 === $is_id ){
904
905 $search_booking_id = substr( trim( $params['keyword'] ), 3 );
906 $search_booking_id_arr = explode( ',', $search_booking_id ); // Get array of booking ID: from 'id:200,201,15' we get [200,201,15]
907
908 $sql_where_arr = array();
909 $sql_args = array(); // It's last WHERE in a list so all previous arguments ($sql_args) we are resetting
910
911 foreach ( $search_booking_id_arr as $bk_id ) {
912
913 $sql_where_arr[] = ' bk.booking_id = %d ';
914 $sql_args[] = intval( $bk_id );
915 }
916
917 $sql['where'] = " WHERE ( " . implode( ' OR ', $sql_where_arr ) . ") ";
918
919 $sql['where'] = apply_bk_filter('update_where_sql_for_getting_bookings_in_multiuser', $sql['where'] ); // Add 'AND bk.booking_type IN ( $user_resources )' to the end of Where
920 }
921 }
922
923 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
924
925
926 switch ( $params['wh_sort'] ) {
927 case 'booking_id__asc':
928 $order_by = 'booking_id ASC ';
929 break;
930 case 'booking_id__desc':
931 $order_by = 'booking_id DESC ';
932 break;
933 case 'dates__asc':
934 $order_by = 'sort_date ASC ';
935 break;
936 case 'dates__desc':
937 $order_by = 'sort_date DESC ';
938 break;
939 case 'resource__asc':
940 $order_by = 'booking_type ASC ';
941 break;
942 case 'resource__desc':
943 $order_by = 'booking_type DESC ';
944 break;
945 case 'cost__asc':
946 $order_by = 'cost ASC ';
947 break;
948 case 'cost__desc':
949 $order_by = 'cost DESC ';
950 break;
951 default:
952 $order_by = 'booking_id ASC ';
953 }
954 $sql['order'] = " ORDER BY bk." . $order_by; // $sql['order'] = " ORDER BY bk." . esc_sql( $params['sort'] ) . ( ( 'DESC' == $params['sort_type'] ) ? " DESC " : " ASC " );
955
956 $sql_args_count = $sql_args; // For SELECT COUNT(*) as count we do not need other parameters
957
958 $sql['limit'] = " LIMIT %d, %d ";
959
960 $sql_args[] = ( $params['page_num'] - 1 ) * $params['page_items_count'];
961 $sql_args[] = $params['page_items_count'];
962
963
964
965 /**
966 * Good Practice: https://blog.ircmaxell.com/2017/10/disclosure-wordpress-wpdb-sql-injection-technical.html
967 * fixed in WordPress 4.8.3
968 *
969 $where = "WHERE foo = %s";
970 $args = [$_GET['data']];
971 $args[] = 1;
972 $args[] = 2;
973 $query = $wpdb->prepare("SELECT * FROM something $where LIMIT %d, %d", $args);
974 *
975 */
976
977 ////////////////////////////////////////////////////////////////////////////////////////////////////////////
978 // SELECT at this specific PAGE /////////////////////////////////////////////////////////////////
979 ////////////////////////////////////////////////////////////////////////////////////////////////////////////
980 /* phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.PreparedSQLPlaceholders.UnfinishedPrepare */
981 $sql_prepared = $wpdb->prepare( $sql['start_select'] . $sql['from'] . $sql['where'] . $sql['order'] . $sql['limit'], $sql_args );
982 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.NotPrepared, PluginCheck.Security.DirectDB.UnescapedDBParameter
983 $bookings_sql_obj = $wpdb->get_results( $sql_prepared );
984
985
986 ////////////////////////////////////////////////////////////////////////////////////////////////////////////
987 // COUNT of items with this WHERE ///////////////////////////////////////////////////////////////////
988 ////////////////////////////////////////////////////////////////////////////////////////////////////////////
989 $sql_for_listing_count = $sql['start_count']
990 . $sql['from']
991 . $sql['where'];
992
993 if ( false === strpos( $sql_for_listing_count, '%' ) ) {
994
995 $sql_prepared = $sql_for_listing_count;
996
997 } else {
998 /* phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.PreparedSQLPlaceholders.UnfinishedPrepare */
999 $sql_prepared = $wpdb->prepare( $sql_for_listing_count, $sql_args_count );
1000 }
1001 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.NotPrepared, PluginCheck.Security.DirectDB.UnescapedDBParameter
1002 $bookings_count = $wpdb->get_results( $sql_prepared );
1003 $bookings_count = ( ( count( $bookings_count ) > 0 ) ? $bookings_count[0]->count : 0 );
1004
1005 return array(
1006 'count' => $bookings_count
1007 , 'bookings' => $bookings_sql_obj
1008 );
1009 }
1010
1011 // W H E R E C O N D I T I O N S
1012
1013 /**
1014 * Get SQL W H E R E conditions for D a t e s of bookings
1015 *
1016 * @param string $wh_booking_date - Parameter from Booking Listing request (usually its number)
1017 * @param string $wh_booking_date2 - Parameter from Booking Listing request (usually its number)
1018 * @param string $pref - Optional. Prefix for table.
1019 * @return string - WHERE conditions for SQL
1020 */
1021 function wpbc_ajx__sql_where_for_dates( $wh_booking_date, $wh_booking_date2, $pref = 'dt.' ) {
1022
1023 $wh_booking_date = (string) $wh_booking_date;
1024 $wh_booking_date2 = (string) $wh_booking_date2;
1025
1026 $sql_where= '';
1027 if ($pref == 'dt.') { $and_pre = ' AND '; $and_suf = ''; }
1028 else { $and_pre = ''; $and_suf = ' AND '; }
1029
1030 // Actual
1031 if ( ( ( $wh_booking_date === '' ) && ( $wh_booking_date2 === '' ) ) || ($wh_booking_date === '0') ) {
1032 $sql_where = $and_pre."( ".$pref."booking_date >= (" . wpbc_sql_date_math_expr_explicit( "- INTERVAL '00:00:01' HOUR_SECOND", 'curdate' ) . ") ) ".$and_suf ; // FixIn: 8.5.2.14.
1033
1034 } else if ($wh_booking_date === '1') { // Today // FixIn: 7.1.2.8.
1035 $sql_where = $and_pre."( ".$pref."booking_date <= (" . wpbc_sql_date_math_expr_explicit( "+ INTERVAL '23:59:59' HOUR_SECOND", 'curdate' ) . ") ) ".$and_suf ;
1036 $sql_where .= $and_pre."( ".$pref."booking_date >= (" . wpbc_sql_date_math_expr_explicit( "- INTERVAL '00:00:01' HOUR_SECOND", 'curdate' ) . ") ) ".$and_suf ; // FixIn: 8.4.7.21.
1037
1038
1039 } else if ($wh_booking_date === '2') { // Previous
1040 $sql_where = $and_pre."( ".$pref."booking_date <= (" . wpbc_sql_date_math_expr_explicit( "- INTERVAL '00:00:01' HOUR_SECOND", 'curdate' ) . ") ) ".$and_suf ; // FixIn: 8.5.2.16.
1041
1042 } else if ($wh_booking_date === '3') { // All
1043 $sql_where = '';
1044
1045 } else if ($wh_booking_date === '4') { // Next
1046 $wh_booking_date2 = intval( $wh_booking_date2 ); // FixIn: 10.14.16.1.
1047 $sql_where = $and_pre."( ".$pref."booking_date <= (" . wpbc_sql_date_math_expr_explicit( "+ INTERVAL ". $wh_booking_date2 . " DAY", 'curdate' ) . ") ) ".$and_suf ;
1048 // $sql_where .= $and_pre."( ".$pref."booking_date >= (" . wpbc_sql_date_math_expr_explicit( "- INTERVAL 1 DAY", 'curdate' ) . ") ) ".$and_suf ;
1049 $sql_where .= $and_pre."( ".$pref."booking_date > ( " . wpbc_sql_date_math_expr_explicit('', 'curdate') . " ) ) ".$and_suf ; // FixIn: 8.0.1.1.
1050
1051 } else if ($wh_booking_date === '5') { // Prior
1052 $wh_booking_date2 = str_replace('-', '', $wh_booking_date2);
1053 $wh_booking_date2 = intval( $wh_booking_date2 ); // FixIn: 10.14.16.1.
1054 $sql_where = $and_pre."( ".$pref."booking_date >= (" . wpbc_sql_date_math_expr_explicit( "- INTERVAL ". $wh_booking_date2 . " DAY", 'curdate' ) . ") ) ".$and_suf ;
1055 $sql_where .= $and_pre."( ".$pref."booking_date <= (" . wpbc_sql_date_math_expr_explicit( "+ INTERVAL 1 DAY", 'curdate' ) . ") ) ".$and_suf ;
1056
1057 } else if ($wh_booking_date === '7') { // Check In date - Today/Tomorrow
1058 $sql_where = $and_pre."( ".$pref."booking_date <= (" . wpbc_sql_date_math_expr_explicit( "+ INTERVAL '47:59:59' HOUR_SECOND", 'curdate' ) . ") ) ".$and_suf ;
1059 $sql_where .= $and_pre."( ".$pref."booking_date >= (" . wpbc_sql_date_math_expr_explicit( "+ INTERVAL 1 DAY", 'curdate' ) . ") ) ".$and_suf ;
1060
1061 } else if ($wh_booking_date === '8') { // Check Out date - Tomorrow
1062 $sql_where = $and_pre."( ".$pref."booking_date <= (" . wpbc_sql_date_math_expr_explicit( "+ INTERVAL '47:59:59' HOUR_SECOND", 'curdate' ) . ") ) ".$and_suf ;
1063 $sql_where .= $and_pre."( ".$pref."booking_date >= (" . wpbc_sql_date_math_expr_explicit( "+ INTERVAL 1 DAY", 'curdate' ) . ") ) ".$and_suf ;
1064
1065 } else if ( ( $wh_booking_date === '9' ) || ( $wh_booking_date === '10' ) || ( $wh_booking_date === '11' ) ) { // Today check in/out
1066 $sql_where = $and_pre."( ".$pref."booking_date <= (" . wpbc_sql_date_math_expr_explicit( "+ INTERVAL 1 DAY", 'curdate' ) . ") ) ".$and_suf ;
1067 $sql_where .= $and_pre."( ".$pref."booking_date >= (" . wpbc_sql_date_math_expr_explicit( "- INTERVAL 1 DAY", 'curdate' ) . ") ) ".$and_suf ;
1068
1069 } else { // Fixed
1070
1071 $wh_booking_date = wpbc_sanitize_date( $wh_booking_date );
1072 $wh_booking_date2 = wpbc_sanitize_date( $wh_booking_date2 );
1073
1074 /*
1075 if ( $wh_booking_date !== '' ){
1076 $sql_where .= $and_pre . "( " . $pref . "booking_date >= ( '" . $wh_booking_date . "' - INTERVAL '00:00:01' HOUR_SECOND ) ) " . $and_suf;
1077 }
1078 if ( $wh_booking_date2 !== '' ) {
1079 $sql_where .= $and_pre . "( " . $pref . "booking_date <= ( '" . $wh_booking_date2 . "' + INTERVAL '23:59:59' HOUR_SECOND ) ) " . $and_suf;
1080 }
1081 */
1082
1083 if ( $wh_booking_date !== '' ) {
1084 if ( strpos( $wh_booking_date, ':' ) === false ) {
1085 $sql_where .= $and_pre . "( " . $pref . "booking_date >= '" . $wh_booking_date . " 00:00:00' ) " . $and_suf;
1086 } else {
1087 $sql_where .= $and_pre . "( " . $pref . "booking_date >= '" . $wh_booking_date . "' ) " . $and_suf;
1088 }
1089 }
1090
1091 if ( $wh_booking_date2 !== '' ) {
1092 if ( strpos( $wh_booking_date2, ':' ) === false ) {
1093 $sql_where .= $and_pre . "( " . $pref . "booking_date <= '" . $wh_booking_date2 . " 23:59:59' ) " . $and_suf;
1094 } else {
1095 $sql_where .= $and_pre . "( " . $pref . "booking_date <= '" . $wh_booking_date2 . "' ) " . $and_suf;
1096 }
1097 }
1098
1099
1100 }
1101
1102 return $sql_where;
1103 }
1104
1105
1106 /**
1107 * Get SQL W H E R E conditions for M o d i f i c a t i o n D a t e of bookings
1108 *
1109 * @param string $wh_modification_date - Parameter from Booking Listing request (usually its number)
1110 * @param string $wh_modification_date2 - Parameter from Booking Listing request (usually its number)
1111 * @param string $pref - Optional. Prefix for table.
1112 * @return string - WHERE conditions for SQL
1113 */
1114 function wpbc_ajx__sql_where_for_modification_date( $wh_modification_date, $wh_modification_date2, $pref = 'bk.' ) {
1115
1116 $sql_where = '';
1117
1118 if ($pref == 'bk.') { $and_pre = ' AND '; $and_suf = ''; }
1119 else { $and_pre = ''; $and_suf = ' AND '; }
1120
1121 if ($wh_modification_date === '1') { // Today
1122 $sql_where = $and_pre."( ".$pref."modification_date <= (" . wpbc_sql_date_math_expr_explicit( "+ INTERVAL '23:59:59' HOUR_SECOND", 'curdate' ) . ") ) ".$and_suf ; // FixIn: 8.4.7.22.
1123 $sql_where .= $and_pre."( ".$pref."modification_date >= (" . wpbc_sql_date_math_expr_explicit( "- INTERVAL '00:00:01' HOUR_SECOND", 'curdate' ) . ") ) ".$and_suf ; // FixIn: 8.4.7.22.
1124
1125 } else if ($wh_modification_date === '3') { // All
1126 $sql_where = '';
1127
1128 } else if ($wh_modification_date === '5') { // Prior
1129 $wh_modification_date2 = str_replace('-', '', $wh_modification_date2);
1130 $wh_modification_date2 = intval( $wh_modification_date2 ); // FixIn: 10.14.16.1.
1131 $sql_where = $and_pre."( ".$pref."modification_date >= (" . wpbc_sql_date_math_expr_explicit( "- INTERVAL ". $wh_modification_date2 . " DAY", 'curdate' ) . ") ) ".$and_suf ;
1132 $sql_where .= $and_pre."( ".$pref."modification_date <= (" . wpbc_sql_date_math_expr_explicit( "+ INTERVAL 1 DAY", 'curdate' ) . ") ) ".$and_suf ;
1133
1134 } else { // Fixed
1135
1136 $wh_modification_date = wpbc_sanitize_date( $wh_modification_date ); // FixIn: 9.4.4.1.
1137 $wh_modification_date2 = wpbc_sanitize_date( $wh_modification_date2 );
1138
1139 if ( $wh_modification_date !== '' )
1140 $sql_where.= $and_pre."( ".$pref."modification_date >= ( '" . $wh_modification_date . "' - INTERVAL '00:00:01' HOUR_SECOND ) ) ".$and_suf;
1141
1142 if ( $wh_modification_date2 !== '' )
1143 $sql_where.= $and_pre."( ".$pref."modification_date <= ( '" . $wh_modification_date2 . "' + INTERVAL '23:59:59' HOUR_SECOND ) ) ".$and_suf;
1144 }
1145
1146 return $sql_where;
1147 }
1148
1149
1150 /**
1151 * Get SQL W H E R E conditions for B o o k i n g R e s o u r c e s
1152 *
1153 * @param $wh_booking_type
1154 * @param $wh_approved
1155 * @param $wh_booking_date
1156 * @param $wh_booking_date2
1157 *
1158 * @return string - SQL
1159 */
1160 function wpbc_ajx__sql_where_for_resources( $wh_booking_type, $wh_approved, $wh_booking_date, $wh_booking_date2 ){
1161 global $wpdb;
1162
1163 if ( ! class_exists( 'wpdev_bk_personal' ) ) {
1164 return '';
1165 }
1166
1167 if ( is_array( $wh_booking_type ) ) {
1168 $wh_booking_type = implode( ',', $wh_booking_type );
1169 }
1170
1171 $sql_where = '';
1172
1173 if ( '0' === $wh_booking_type ) { // All booking resources
1174 // Get all booking resources of this user
1175 $resources_sql_arr = wpbc_ajx_get_all_booking_resources_arr();
1176 $wh_booking_type = implode( ',', array_keys( $resources_sql_arr ) );
1177 //$resources_arr = wpbc_ajx_arrange_booking_resources_arr( $resources_sql_arr );
1178 }
1179
1180 if ( '-1' === $wh_booking_type ) { // Lost booking resources
1181
1182 $is_show_lost = true;
1183
1184 if ( class_exists( 'wpdev_bk_multiuser' ) ) { // MultiUser - Only for super booking admin user
1185
1186 $user_bk_id = ( isset( $_REQUEST['wpbc_ajx_user_id'] ) ) ? intval( $_REQUEST['wpbc_ajx_user_id'] ) : wpbc_get_current_user_id(); // phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.NonceVerification.Missing
1187
1188 $is_user_super_admin = apply_bk_filter( 'is_user_super_admin', $user_bk_id );
1189
1190 if ( ! $is_user_super_admin ) {
1191 $is_show_lost = false; // For regular user show all bookings from the booking resources that belong to this user.
1192 $sql_where .= " AND bk.booking_type IN ( SELECT DISTINCT booking_type_id FROM {$wpdb->prefix}bookingtypes WHERE users = " . $user_bk_id . " ) ";
1193 }
1194 }
1195
1196 // "Lost" bookings in deleted booking resources
1197 if ( $is_show_lost ) {
1198 $sql_where .= " AND bk.booking_type NOT IN ( SELECT DISTINCT booking_type_id FROM {$wpdb->prefix}bookingtypes ) ";
1199 }
1200
1201 } else if ( ! empty( $wh_booking_type ) ) {
1202 // P
1203 $sql_where .= " AND ( ";
1204 $sql_where .= " ( bk.booking_type IN ( " . $wh_booking_type . " ) ) ";
1205
1206 // BL - Show bookings from child booking resources, if was selected only parent booking resource
1207 $is_show_bookings_for_child_resources = true;
1208 if ( $is_show_bookings_for_child_resources ) {
1209 $sql_where .= wpbc_ajx__sql_where_for_resources_bl( $wh_booking_type, $wh_approved, $wh_booking_date, $wh_booking_date2 );
1210 }
1211
1212 // P
1213 $sql_where .= " ) ";
1214
1215 // MU - Check if searching bookings are belongs to specific user in Booking Calendar MultiUser version
1216 $sql_where = apply_bk_filter( 'update_where_sql_for_getting_bookings_in_multiuser', $sql_where );
1217 }
1218
1219 return $sql_where;
1220 }
1221
1222
1223 /**
1224 * Get SQL W H E R E conditions for B o o k i n g R e s o u r c e s BL - Capacity
1225 *
1226 * @param $wh_booking_type
1227 * @param $wh_approved
1228 * @param $wh_booking_date
1229 * @param $wh_booking_date2
1230 *
1231 * @return string - SQL
1232 */
1233 function wpbc_ajx__sql_where_for_resources_bl( $wh_booking_type, $wh_approved, $wh_booking_date, $wh_booking_date2 ){
1234
1235 if ( ! class_exists( 'wpdev_bk_biz_l' ) ) {
1236 return '';
1237 }
1238
1239 global $wpdb;
1240 $sql_where = '';
1241
1242 // BL // Childs in dif sub resources
1243 $sql_where.= " OR ( bk.booking_id IN (
1244 SELECT DISTINCT booking_id
1245 FROM {$wpdb->prefix}bookingdates as dtt
1246 WHERE " ;
1247 if ($wh_approved !== '')
1248 $sql_where.= " dtt.approved = $wh_approved AND " ;
1249 $sql_where .= wpbc_ajx__sql_where_for_dates( $wh_booking_date, $wh_booking_date2, 'dtt.' );
1250
1251 $sql_where.= " (
1252 dtt.type_id IN ( ". $wh_booking_type ." )
1253 OR dtt.type_id IN (
1254 SELECT booking_type_id
1255 FROM {$wpdb->prefix}bookingtypes as bt
1256 WHERE bt.parent IN ( ". $wh_booking_type ." )
1257 )
1258 )
1259 )
1260 ) " ;
1261
1262 // phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.NonceVerification.Missing
1263 if ( ( isset($_REQUEST['tab']) ) && ( $_REQUEST['tab']== 'vm_calendar' ) ) {
1264
1265 // Skip the bookings from the children resources, if we are in the Calendar view mode at the admin panel
1266
1267 } else {
1268 // BL // Just children booking resources
1269 $sql_where .= " OR ( bk.booking_type IN (
1270 SELECT booking_type_id
1271 FROM {$wpdb->prefix}bookingtypes as bt
1272 WHERE bt.parent IN ( " . $wh_booking_type . " )
1273 )
1274 )";
1275 }
1276
1277 return $sql_where;
1278 }
1279
1280
1281 /**
1282 * Get SQL W H E R E conditions for P a y m e n t S t a t u s
1283 *
1284 * @param $wh_pay_status [ 'any ' ] | ['group_ok'] | ['group_unknown' ] | ['group_pending'] | ['group_failed'] | [ 'user_entered', 'myCustom status' ]
1285 *
1286 * @return array [ string SQL, array ARGS ]
1287 */
1288 function wpbc_ajx__sql_where_for_payment_status( $wh_pay_status_arr ){
1289
1290 // [ 'any ' ] | ['group_ok'] | ['group_unknown' ] | ['group_pending'] | ['group_failed'] | [ 'user_entered', 'myCustom status' ]
1291
1292 $wh_pay_status_custom = '';
1293 $wh_pay_status = '';
1294
1295 if ( ! empty( $wh_pay_status_arr ) ) {
1296
1297 if ( count( $wh_pay_status_arr ) > 1 ) {
1298 $wh_pay_status_custom = $wh_pay_status_arr[1];
1299 }
1300 $wh_pay_status = $wh_pay_status_arr[0];
1301 }
1302
1303 $sql_where = '';
1304 $sql_args = array();
1305
1306 if ( ( '' != $wh_pay_status ) && ( 'all' != $wh_pay_status ) ) {
1307
1308 $sql_where .= " AND ( ";
1309
1310 // Check firstly if we are selected some goup of payment status
1311 if ( $wh_pay_status == 'group_ok' ) { // SUCCESS
1312
1313 $payment_status = wpbc_get_payment_status_ok();
1314
1315 foreach ( $payment_status as $label ) {
1316 $sql_where .= " ( bk.pay_status = '" . $label . "' ) OR";
1317 }
1318 $sql_where = substr( $sql_where, 0, - 2 );
1319
1320 } else if ( ( $wh_pay_status == 'group_unknown' ) || ( is_numeric( $wh_pay_status_custom ) ) ) { // UNKNOWN
1321
1322 $payment_status = wpbc_get_payment_status_unknown();
1323 foreach ( $payment_status as $label ) {
1324 $sql_where .= " ( bk.pay_status = '" . $label . "' ) OR";
1325 }
1326 //$sql_where = substr($sql_where, 0, -2);
1327 $sql_where .= " ( bk.pay_status = '' ) OR ( bk.pay_status regexp '^[0-9]') ";
1328
1329 } else if ( $wh_pay_status == 'group_pending' ) { // Pending
1330
1331 $payment_status = wpbc_get_payment_status_pending();
1332 foreach ( $payment_status as $label ) {
1333 $sql_where .= " ( bk.pay_status = '" . $label . "' ) OR";
1334 }
1335 $sql_where = substr( $sql_where, 0, - 2 );
1336
1337 } else if ( $wh_pay_status == 'group_failed' ) { // Failed
1338
1339 $payment_status = wpbc_get_payment_status_error();
1340 foreach ( $payment_status as $label ) {
1341 $sql_where .= " ( bk.pay_status = '" . $label . "' ) OR";
1342 }
1343 $sql_where = substr( $sql_where, 0, - 2 );
1344
1345 } else { // CUSTOM Payment Status
1346 $sql_where .= " bk.pay_status = %s ";
1347
1348 // $wh_pay_status_custom = htmlspecialchars_decode( $wh_pay_status_custom ); // ? Convert special HTML entities back to characters: "&#60; - &#62;" to "< - >"
1349 $sql_args[] = $wh_pay_status_custom;
1350 }
1351
1352 $sql_where .= " ) ";
1353 }
1354
1355 return array( $sql_where, $sql_args );
1356 }
1357
1358
1359 /**
1360 * Get SQL W H E R E conditions for C o s t Min - Max
1361 *
1362 * @param $wh_cost_min '' or number
1363 * @param $wh_cost_max '' or number
1364 *
1365 * @return array [ string SQL, array ARGS ]
1366 */
1367 function wpbc_ajx__sql_where_cost_min_max( $wh_cost_min, $wh_cost_max ) {
1368
1369 $sql_where = '';
1370 $sql_args = array();
1371
1372 if ( $wh_cost_min !== '' ) {
1373 $sql_where .= " AND ( bk.cost >= %f ) ";
1374 $sql_args[] = $wh_cost_min;
1375 }
1376 if ( $wh_cost_max !== '' ) {
1377 $sql_where .= " AND ( bk.cost <= %f ) ";
1378 $sql_args[] = $wh_cost_max;
1379 }
1380
1381 return array( $sql_where, $sql_args );
1382
1383 }
1384
1385
1386 /**
1387 * D A T E S - Get array of "Booking Dates" objects from DB
1388 * relative to specific bookings - array of Bookings objects from DB
1389 *
1390 * @param array of object $bookings_sql_obj
1391 *
1392 * @return array of booking dates sql objects
1393 */
1394 function wpbc_ajx_get__booking_dates_obj__sql( $bookings_sql_obj ){
1395
1396 global $wpdb;
1397 $db_names = wpbc_get_db_names();
1398
1399 // Get list of booking ID from bookings obj ///////////////////////////////////////////////////////////////
1400 $booking_id_list = array();
1401 foreach ( $bookings_sql_obj as $booking ) {
1402 $booking_id_list[] = intval( $booking->booking_id );
1403 }
1404 $booking_id_list = array_unique( $booking_id_list ); // remove duplicates
1405 $booking_id_list = implode( ",", $booking_id_list );
1406 ////////////////////////////////////////////////////////////////////////////////////////////////////////////
1407
1408
1409 if ( ! empty( $booking_id_list ) ) { // Get Dates for all our Bookings
1410
1411 $sql = "SELECT *
1412 FROM {$db_names['dates']} as dt
1413 WHERE dt.booking_id in ( {$booking_id_list} ) ";
1414
1415 if ( class_exists( 'wpdev_bk_biz_l' ) ) {
1416 $sql .= " ORDER BY booking_id, type_id, booking_date ";
1417 } else {
1418 $sql .= " ORDER BY booking_id, booking_date ";
1419 }
1420 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.NotPrepared, PluginCheck.Security.DirectDB.UnescapedDBParameter
1421 $booking_dates_sql_obj = $wpdb->get_results( $sql );
1422 } else {
1423 $booking_dates_sql_obj = array();
1424 }
1425
1426 return $booking_dates_sql_obj;
1427 }
1428
1429
1430 /**
1431 * S Q L - B O O K I N G S - Get array of "Bookings" objects from DB
1432 * based on request params
1433 *
1434 * @param array $request_params
1435 * @param array of object $bookings_sql_obj
1436 *
1437 * @return array of array( booking dates, $bookings_count) array( sql objects, int )
1438 */
1439 function wpbc_ajx_get__remove_bookings__where_dates_outside($request_params, $bookings_obj, $bookings_count){
1440
1441 $is_id = strpos( trim( strtolower( $request_params['keyword'] ) ) , 'id:' );
1442 if ( false !== $is_id ) {
1443 return array( $bookings_obj, $bookings_count );
1444 }
1445 // W H E R E : D A T E S --------------------------------------------------------------------------------
1446 if (1){
1447 if ( is_array( $request_params['wh_booking_date'] ) ) {
1448 $wh_booking_date_arr = array_replace( array( '', '' ), $request_params['wh_booking_date'] ); // Always have minimum 2 values in arr
1449 } else {
1450 $wh_booking_date_arr = array( '', '' );
1451 }
1452
1453 if ( count( $wh_booking_date_arr ) > 2 ) {
1454 $removed_el = array_shift( $wh_booking_date_arr ); // Remove an element off the beginning of array
1455 }
1456 }
1457
1458 $wh_booking_date = (string) $wh_booking_date_arr[0];
1459 $wh_booking_date2 =(string) $wh_booking_date_arr[1];
1460
1461 // Check In date - Tomorrow
1462 if ( $wh_booking_date === '7' ) {
1463
1464 $today_mysql_format = date_i18n( 'Y-m-d', time() + ( get_option( 'gmt_offset' ) * HOUR_IN_SECONDS ) + DAY_IN_SECONDS ); // Tommorow day with gmt offset
1465 foreach ( $bookings_obj as $bc_id => $bc_value ) {
1466 $check_in_date = $bc_value->short_dates[0];
1467 $check_in_date = explode( ' ', $check_in_date );
1468 $check_in_date = $check_in_date[0]; // 2014-02-25
1469 if ( $today_mysql_format != $check_in_date ) {
1470 unset( $bookings_obj[ $bc_id ] );
1471 $bookings_count--;
1472 }
1473 }
1474 }
1475
1476 // Check Out date - Tomorrow
1477 if ( $wh_booking_date === '8' ) {
1478
1479 $tomorrow_mysql_format = date_i18n( 'Y-m-d', time() + ( get_option( 'gmt_offset' ) * HOUR_IN_SECONDS ) + DAY_IN_SECONDS ); // Tommorow day with gmt offset
1480 foreach ( $bookings_obj as $bc_id => $bc_value ) {
1481 if ( 1 == count( $bc_value->short_dates ) ) {
1482 $check_out_date = $bc_value->short_dates[0];
1483 } else {
1484 $check_out_date = $bc_value->short_dates[2];
1485 }
1486 $check_out_date = explode( ' ', $check_out_date );
1487 $check_out_date = $check_out_date[0]; // 2014-02-25
1488 if ( $tomorrow_mysql_format != $check_out_date ) {
1489 unset( $bookings_obj[ $bc_id ] );
1490 $bookings_count --;
1491 }
1492 }
1493 }
1494
1495 // Today == check in/out | Today = Check in | Today = Check out
1496 if ( ( $wh_booking_date === '9' ) || ( $wh_booking_date === '10' ) || ( $wh_booking_date === '11' ) ) {
1497
1498 $today_mysql_format = date_i18n( 'Y-m-d', time() + ( get_option( 'gmt_offset' ) * HOUR_IN_SECONDS ) + 0 * DAY_IN_SECONDS ); // Today day with gmt offset
1499
1500 foreach ( $bookings_obj as $bc_id => $bc_value ) {
1501
1502 $check_in_date = $bc_value->short_dates[0];
1503 $check_in_date = explode( ' ', $check_in_date );
1504 $check_in_date = $check_in_date[0]; // 2014-02-25
1505
1506 if ( count( $bc_value->short_dates ) == 1 ) {
1507 $check_out_date = $bc_value->short_dates[0];
1508 } else {
1509 $check_out_date = $bc_value->short_dates[2];
1510 }
1511 $check_out_date = explode( ' ', $check_out_date );
1512 $check_out_date = $check_out_date[0]; // 2014-02-25
1513
1514 // Check In
1515 if ( $wh_booking_date === '10' ) {
1516 if ( $today_mysql_format != $check_in_date ) {
1517 unset( $bookings_obj[ $bc_id ] );
1518 $bookings_count --;
1519 }
1520 }
1521 // Check out
1522 if ( $wh_booking_date === '11' ) {
1523 if ( $today_mysql_format != $check_out_date ) {
1524 unset( $bookings_obj[ $bc_id ] );
1525 $bookings_count --;
1526 }
1527 }
1528 // Check In | Check out // FixIn: 9.6.3.12.
1529 if ( $wh_booking_date === '9' ) {
1530 if ( ( $today_mysql_format != $check_in_date ) && ( $today_mysql_format != $check_out_date ) ) {
1531 unset( $bookings_obj[ $bc_id ] );
1532 $bookings_count --;
1533 }
1534 }
1535
1536 }
1537 }
1538
1539 return array( $bookings_obj, $bookings_count );
1540 }
1541
1542 /**
1543 * Get array of bookings with dates (wide and short dates view)
1544 * after inserting dates into the bookings
1545 *
1546 * @param $bookings_obj Array (
1547 [0] => stdClass Object (
1548 [booking_id] => 182
1549 [trash] => 0
1550 [sync_gid] =>
1551 [is_new] => 1
1552 [status] =>
1553 [sort_date] => 2023-01-23 10:00:01
1554 [modification_date] => 2022-04-18 12:23:30
1555 [form] => selectbox-one^rangetime2^10:00 - 12:00~text^name2^rr~text^secondname2^hjk~email^email2^hyui@nbco.csdf~text^phone2^h~text^address2^khj~text^city2^e~text^postcode2^hj~selectbox-one^country2^HT~selectbox-one^visitors2^1~selectbox-one^children2^0~textarea^details2^djkh~checkbox^term_and_condition2[]^I Accept term and conditions
1556 [hash] => a1ae510d8fee961b7f8ae53101632151
1557 [booking_type] => 2
1558 [remark] =>
1559 [cost] => 75.00
1560 [pay_status] => 165028101080.84
1561 [pay_request] => 0
1562 )
1563 [1] => stdClass Object, ....
1564 * @param $booking_dates_obj Array (
1565 [0] => stdClass Object (
1566 [booking_dates_id] => 294
1567 [booking_id] => 147
1568 [booking_date] => 2022-06-27 12:00:01
1569 [approved] => 0
1570 [type_id] =>
1571 )
1572 [1] => stdClass Object, ...
1573 *
1574 * @return array Array (
1575 * [182] => stdClass Object (
1576 * ... many other props ....
1577 * [id] => 182
1578 * [approved] => 0
1579 * [dates] => Array (
1580 * [0] => 2023-01-23 10:00:01
1581 * [1] => 2023-01-25 00:00:00
1582 * [2] => 2023-01-27 12:00:02
1583 * )
1584 * [child_id] => Array (
1585 * [0] =>
1586 * [1] =>
1587 * [2] =>
1588 * )
1589 * [short_dates] => Array (
1590 * [0] => 2023-01-23 10:00:01
1591 * [1] => ,
1592 * [2] => 2023-01-25 00:00:00
1593 * [3] => ,
1594 * [4] => 2023-01-27 12:00:02
1595 * )
1596 * [short_dates_child_id] => Array (
1597 * [0] =>
1598 * [1] =>
1599 * [2] =>
1600 * [3] =>
1601 * [4] =>
1602 * )
1603 * )
1604 * [181] => stdClass Object (
1605 * ....
1606 */
1607 function wpbc_ajx_include_bookingdates_in_the_bookings( $bookings_obj, $booking_dates_obj ){
1608
1609 $bookings_arr = array();
1610 foreach ( $bookings_obj as $booking ) {
1611
1612 $bookings_arr[$booking->booking_id] = new StdClass;
1613 $bookings_arr[$booking->booking_id]->booking_db = $booking;
1614 $bookings_arr[$booking->booking_id]->id = $booking->booking_id;
1615 $bookings_arr[$booking->booking_id]->approved = 0;
1616 $bookings_arr[$booking->booking_id]->dates = array();
1617 $bookings_arr[$booking->booking_id]->child_id = array();
1618 /*
1619 $resource_id = (isset( $booking->booking_type )) ? $booking->booking_type : '1';
1620
1621 // booking Form parse can be here
1622
1623
1624 if ( ( isset( $booking->sync_gid ) ) && (!empty( $booking->sync_gid )) ) {
1625 $booking->form .= "~text^sync_gid{$booking->booking_type}^{$booking->sync_gid}";
1626 }
1627
1628 $cont = wpbc__legacy__get_form_content_arr( $booking->form
1629 , $resource_id
1630 , ''
1631 , array(
1632 'booking_id' => $booking->booking_id
1633 , 'resource_title' => (isset( $booking_types[$booking->booking_type] )) ? $booking_types[$booking->booking_type] : ''
1634 )
1635 );
1636 $search = array( "'(<br[ ]?[/]?>)+'si", "'(<[/]?p[ ]?>)+'si" );
1637 $replace = array( "&nbsp;&nbsp;", " &nbsp; ", " &nbsp; " );
1638 $cont['content'] = preg_replace( $search, $replace, $cont['content'] );
1639 //debuge( htmlentities( $cont['content'] ) );die;
1640 $bookings_arr[$booking->booking_id]->form_show = $cont['content'];
1641 unset( $cont['content'] );
1642 $bookings_arr[$booking->booking_id]->form_data = $cont;
1643
1644 /**/
1645 }
1646
1647 // Wide dates in bookings
1648 foreach ( $booking_dates_obj as $date ) {
1649 $bookings_arr[ $date->booking_id ]->approved = $date->approved;
1650
1651 $bookings_arr[ $date->booking_id ]->dates[] = $date->booking_date;
1652 $bookings_arr[ $date->booking_id ]->child_id[] = ( isset( $date->type_id ) ) ? $date->type_id : '';
1653 }
1654
1655 // Short dates
1656 foreach ( $bookings_arr as $booking_id => $booking ) {
1657
1658 if ( count( $booking->dates ) == 0 ) { continue; } // If no dates, then skip
1659
1660 $bookings_arr[ $booking_id ]->short_dates = array( $booking->dates[0] ); // First Day
1661 $bookings_arr[ $booking_id ]->short_dates_child_id = array( $bookings_arr[ $booking_id ]->child_id[0] );
1662 $previous = array(
1663 'date' => $booking->dates[0],
1664 'date_index' => 0,
1665 'separator' => false
1666 );
1667
1668 if ( count( $booking->dates ) == 1 ) { continue; } // if 1 date, then skip
1669
1670
1671 for ( $date_indx = 1; $date_indx < ( count( $booking->dates ) ); $date_indx ++ ) { // Start from 2nd day
1672
1673 $date = $booking->dates[ $date_indx ];
1674
1675 // if ( wpbc_is_next_day( $date, $previous['date'] ) ) {
1676 $next_day_if__check_in__then__check_out = true;
1677 if ( wpbc_is_less_than_next_day( $date, $previous['date'], $next_day_if__check_in__then__check_out ) ) {
1678
1679 if ( '-' != $previous['separator'] ) {
1680 $bookings_arr[ $booking_id ]->short_dates[] = '-';
1681 $bookings_arr[ $booking_id ]->short_dates_child_id[] = '';
1682 }
1683 $previous['separator'] = '-';
1684
1685 } else {
1686
1687 if ( '-' == $previous['separator'] ) {
1688
1689 $bookings_arr[ $booking_id ]->short_dates[] = $previous['date'];
1690 $bookings_arr[ $booking_id ]->short_dates_child_id[] = $bookings_arr[ $booking_id ]->child_id[ $previous['date_index'] ];
1691 }
1692 $bookings_arr[ $booking_id ]->short_dates[] = ',';
1693 $bookings_arr[ $booking_id ]->short_dates_child_id[] = '';
1694
1695 $bookings_arr[ $booking_id ]->short_dates[] = $date;
1696 $bookings_arr[ $booking_id ]->short_dates_child_id[] = $bookings_arr[ $booking_id ]->child_id[ $date_indx ];
1697
1698 $previous['separator'] = ',';
1699 }
1700
1701 $previous['date'] = $date;
1702 $previous['date_index'] = $date_indx;
1703
1704 } // dates loop: $date_indx => $date
1705
1706 if ( '-' == $previous['separator'] ) {
1707 $bookings_arr[ $booking_id ]->short_dates[] = $previous['date'];
1708 $bookings_arr[ $booking_id ]->short_dates_child_id[] = $bookings_arr[ $booking_id ]->child_id[ $previous['date_index'] ];
1709 }
1710
1711 } // bookings loop: $booking_id => $booking
1712
1713 return $bookings_arr;
1714 }
1715
1716
1717 function wpbc_ajx_parse_bookings( $bookings_arr, $resources_arr ) {
1718
1719 $user_id = ( isset( $_REQUEST['wpbc_ajx_user_id'] ) ) ? intval( $_REQUEST['wpbc_ajx_user_id'] ) : wpbc_get_current_user_id(); // phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.NonceVerification.Missing
1720
1721 foreach ( $bookings_arr as $booking_id => $booking ) {
1722
1723 // Booking resource ------------------------------------------------------------------------------------
1724 $resource_id = ( isset( $booking->booking_db->booking_type ) ) ? $booking->booking_db->booking_type : '1';
1725 $resource_title = '';
1726 $resource_owner_user = $user_id;
1727
1728 if ( class_exists( 'wpdev_bk_personal' ) ) {
1729 $resource_title = ( isset( $resources_arr[ $resource_id ] ) ) ? $resources_arr[ $resource_id ]['title'] : __( 'Resource not exist', 'booking' );
1730 $resource_title = wpbc_lang( $resource_title );
1731 }
1732 if ( class_exists( 'wpdev_bk_multiuser' ) ) {
1733 $resource_owner_user = ( isset( $resources_arr[ $resource_id ] ) ) ? $resources_arr[ $resource_id ]['users'] : $user_id;
1734 }
1735
1736 $resource_title_listing = $resource_title;
1737 $resource_id_listing = $resource_id;
1738 $child_resource_id_arr = array();
1739 if ( ( class_exists( 'wpdev_bk_biz_l' ) ) && ( ! empty( $booking->child_id ) ) && ( is_array( $booking->child_id ) ) ) {
1740 foreach ( $booking->child_id as $child_resource_id ) {
1741 if ( ! empty( $child_resource_id ) ) {
1742 $child_resource_id_arr[] = (int) $child_resource_id;
1743 }
1744 }
1745 $child_resource_id_arr = array_values( array_unique( $child_resource_id_arr ) );
1746
1747 if ( ( 1 === count( $child_resource_id_arr ) ) && ( isset( $resources_arr[ $child_resource_id_arr[0] ] ) ) ) {
1748 $resource_id_listing = $child_resource_id_arr[0];
1749 $resource_title_listing = wpbc_lang( $resources_arr[ $child_resource_id_arr[0] ]['title'] );
1750 }
1751 }
1752 $show_child_resource_in_dates = ( count( $child_resource_id_arr ) > 1 );
1753
1754 // Parse form fields only from $booking->booking_db->form ------------------------------------------
1755 $booking_data_arr = wpbc_parse_booking_data_fields( $booking->booking_db->form,
1756 array( 'resource_id' => $resource_id )
1757 );
1758
1759
1760 foreach ( $booking_data_arr as $booking_data_arr_key => $booking_data_arr_value ) {
1761 // Booking Listing escaping
1762 $booking_data_arr[$booking_data_arr_key] = wpbc_string__escape__then_convert__n_amp__html( $booking_data_arr_value );
1763 }
1764
1765 // Add system keys to data fields arr, like ( 'booking_id', 'trash', 'sync_gid'... ---------------------
1766 $booking_data_arr = wpbc_add_system_booking_data_fields(
1767 $booking_data_arr,
1768 array_merge(
1769 get_object_vars( $booking->booking_db ),
1770 array( 'id' => $booking->id,
1771 'approved' => $booking->approved,
1772 'wpbc_custom_booking_form' => '' //FixIn: 9.4.3.12 // FixIn: 9.4.4.9.
1773 )
1774 )
1775 , array(
1776 'booking_id',
1777 'trash',
1778 'sync_gid',
1779 'is_new',
1780 'status',
1781 'sort_date',
1782 'modification_date',
1783 'creation_date',
1784 'hash',
1785 'booking_type',
1786 'remark',
1787 'cost',
1788 'pay_status',
1789 'pay_request',
1790 'id',
1791 'approved',
1792 'booking_options',
1793 'wpbc_custom_booking_form', // FixIn: 9.4.3.12.
1794 )
1795 );
1796
1797 // Set dates and times in correct format ---------------------------------------------------------------
1798 $booking_data_arr = wpbc_parse_booking_data_fields_formats( $booking_data_arr );
1799
1800 // Get SHORT / WIDE Dates showing data -----------------------------------------------------------------
1801 $dates_attr = array(
1802 'date_html_tag' => 'span',
1803 'show_child_resource_in_dates' => $show_child_resource_in_dates,
1804 );
1805 $short_dates_content = wpbc_get_formated_dates__short( $booking->short_dates, (bool) $booking->approved, $booking->short_dates_child_id, $resources_arr, $dates_attr );
1806 $wide_dates_content = wpbc_get_formated_dates__wide( $booking->dates, (bool) $booking->approved, $booking->child_id, $resources_arr, $dates_attr );
1807
1808 //------------------------------------------------------------------------------------------------------
1809 // Payment Status
1810 //------------------------------------------------------------------------------------------------------
1811 if ( 1 ) {
1812 $booking_data_arr['is_paid'] = 0; // 0 | 1
1813 $booking_data_arr['pay_print_status'] = ''; // "Unknown" | "Stripe_v3:OK"
1814 // $booking_data_arr['pay_status'] // "165458416073.66" | "Stripe_v3:OK" | "PayPal:Ok"
1815
1816 if ( class_exists( 'wpdev_bk_biz_s' ) ) {
1817
1818 if ( wpbc_is_payment_status_ok( trim( $booking_data_arr['pay_status'] ) ) ) {
1819 $booking_data_arr['is_paid'] = 1;
1820 }
1821
1822 $payment_status_titles = get_payment_status_titles();
1823
1824 $current_payment_status_title = array_search( $booking_data_arr['pay_status'], $payment_status_titles );
1825
1826 if ( $current_payment_status_title === false ) {
1827 $current_payment_status_title = $booking_data_arr['pay_status'];
1828 }
1829
1830 if ( $booking_data_arr['is_paid'] ) {
1831 $booking_data_arr['pay_print_status'] = $booking_data_arr['pay_status'];
1832 if ( $current_payment_status_title == 'Completed' ) {
1833 $booking_data_arr['pay_print_status'] = $current_payment_status_title;
1834 }
1835 } else if ( ( is_numeric( $booking_data_arr['pay_status'] ) ) || ( $booking_data_arr['pay_status'] == '' ) ) {
1836 $booking_data_arr['pay_print_status'] = __( 'Unknown', 'booking' );
1837 } else {
1838 $booking_data_arr['pay_print_status'] = $current_payment_status_title;
1839 }
1840 ////////////////////////////////////////////////////////////////////////////////////////////////////
1841
1842 if ( $booking_data_arr['pay_print_status'] == 'Completed' ) { // FixIn: 8.4.7.11.
1843 $booking_data_arr['pay_print_status'] = __( 'Completed', 'booking' );
1844 }
1845 $real_payment_css = empty( $booking_data_arr['pay_status'] ) ? $current_payment_status_title : $booking_data_arr['pay_status']; // FixIn: 8.7.7.13.
1846 $css_payment_label = 'wpbc_label_payment_status_' . wpbc_check_payment_status( $real_payment_css ); // 'success' | 'pending' | 'unknown' | 'error' // FixIn: 8.7.7.13.
1847
1848 if ( $booking_data_arr['is_paid'] ) {
1849 $css_payment_label .= ' wpbc_label_payment_status_success';
1850 }
1851 $payment_label_template = '<span class="wpbc_label wpbc_label_payment_status ' . $css_payment_label . '">'
1852 . '<span style="font-size:07px;padding: 0 1em 0 0;line-height: 2em;">'
1853 . __( 'Payment', 'booking' )
1854 . '</span> '
1855 . '<span>'
1856 . $booking_data_arr['pay_print_status']
1857 . '</span> '
1858 . '</span>';
1859 } else {
1860 $payment_label_template = '';
1861 }
1862 }
1863
1864 //------------------------------------------------------------------------------------------------------
1865 // Currency
1866 //------------------------------------------------------------------------------------------------------
1867 if ( class_exists( 'wpdev_bk_biz_s' ) ) {
1868 $currency_symbol = wpbc_get_currency_symbol_for_user( $resource_id );
1869 $booking_data_arr['currency_symbol'] = $currency_symbol;
1870 }
1871
1872 //------------------------------------------------------------------------------------------------------
1873 // Add some fields to [ 'parsed_fields' ]
1874 //------------------------------------------------------------------------------------------------------
1875 $booking_data_arr['resource_title'] = $resource_title;
1876 $booking_data_arr['resource_id'] = $resource_id;
1877 $booking_data_arr['resource_title_listing'] = $resource_title_listing;
1878 $booking_data_arr['resource_id_listing'] = $resource_id_listing;
1879 $booking_data_arr['resource_owner_user'] = $resource_owner_user;
1880 //$booking_data_arr['short_dates_content'] = $short_dates_content;
1881 //$booking_data_arr['wide_dates_content'] = $wide_dates_content;
1882
1883 //------------------------------------------------------------------------------------------------------
1884 // Form Show - "Content of booking fields data" form
1885 //------------------------------------------------------------------------------------------------------
1886
1887 $custom_booking_form_name = ( ! empty( $booking_data_arr['wpbc_custom_booking_form'] ) ) ? $booking_data_arr['wpbc_custom_booking_form'] : ''; // FixIn: 9.4.3.12.
1888 $form_show_template = wpbc_get_content_booking_form_show( $resource_id , $custom_booking_form_name ); // <strong>First Name</strong>:<span class="fieldvalue">[name]</span>&nbsp;&nbsp; ...
1889 $parsed_form_show = wpbc_get_parsed_content_booking_form_show( $booking_data_arr, $form_show_template ); // <strong>First Name</strong>:<span class="fieldvalue">John</span>&nbsp;&nbsp; ...
1890
1891 //------------------------------------------------------------------------------------------------------
1892 // Google Calendar link
1893 //------------------------------------------------------------------------------------------------------
1894 $booking_data_arr['google_calendar_link'] = wpbc_booking_do_action__get_google_calendar_link( array(
1895 'form_data' => $booking_data_arr,
1896 'form_show' => $parsed_form_show, //wp_strip_all_tags( $parsed_form_show ),
1897 'dates_short' => $booking->short_dates
1898 ) );
1899 $booking_data_arr['visitorbookingpayurl'] = ( class_exists( 'wpdev_bk_biz_s' ) )
1900 ? apply_bk_filter( 'wpdev_booking_set_booking_edit_link_at_email', '[visitorbookingpayurl]', $booking_id )
1901 : '';
1902 // =====================================================================================================
1903 $bookings_arr[ $booking_id ]->parsed_fields = $booking_data_arr;
1904
1905
1906 // =====================================================================================================
1907 $bookings_arr[ $booking_id ]->templates = array(
1908 'form_show' => $parsed_form_show,
1909 'form_show_simple' => wp_kses( trim( stripslashes( $parsed_form_show ) ),
1910 // array_merge(
1911 array(
1912 'span' => array( 'style'=>true , 'class'=>true , 'id'=>true ),
1913 'b' => array( 'style'=>true , 'class'=>true , 'id'=>true ),
1914 'strong' => array( 'style'=>true , 'class'=>true , 'id'=>true ),
1915 'i' => array( 'style'=>true , 'class'=>true , 'id'=>true ),
1916 'class' => array(),
1917 'style' => array()
1918 )
1919 // , wp_kses_allowed_html( 'post' ) )
1920 ),
1921 'form_show_nohtml' => wp_strip_all_tags( $parsed_form_show ),
1922 'short_dates_content' => $short_dates_content,
1923 'wide_dates_content' => $wide_dates_content,
1924 'payment_label_template' => $payment_label_template
1925 );
1926 }
1927
1928 return $bookings_arr;
1929 }
1930
1931
1932 //TODO: Refactor this function to make this simpler, for prevent of issues in future.
1933 /**
1934 * Get SHORT Dates showing data
1935 *
1936 * @param array $short_dates_arr - Array of dates.
1937 * @param bool $is_approved - true or false
1938 * @param $dates_type_id_arr
1939 * @param $booking_resources_arr
1940 * @param array $attr - [ 'date_html_tag' => 'a' ] .
1941 *
1942 * @return string
1943 */
1944 function wpbc_get_formated_dates__short( $short_dates_arr, $is_approved = false, $dates_type_id_arr = array(), $booking_resources_arr = array(), $attr = array() ) {
1945
1946 $defaults = array(
1947 'date_html_tag' => 'a',
1948 'show_child_resource_in_dates' => true,
1949 );
1950 $params = wp_parse_args( $attr, $defaults );
1951
1952 $css_class_approved = ( $is_approved ) ? 'approved' : '';
1953 $short_dates_content = '';
1954 $short_dates_content_arr = array();
1955 $date_number = 0;
1956 $previous_formatted_date = '';
1957 $previous_short_dates_content_sup;
1958 $previous_sql_date = '';
1959 $previous_short_date_item = '';
1960 foreach ( $short_dates_arr as $dt ) {
1961
1962 if ( '-' === $dt ) {
1963 $short_dates_content_arr[] = '<span class="date_tire"> - </span>';
1964 } elseif ( ',' === $dt ) {
1965 $short_dates_content_arr[] = '<span class="date_tire date_comma">, </span>';
1966 } else {
1967
1968 // Separate recurrent time slots: previous end (...02) followed by the next start (...01).
1969 $is_next_time_slot = (
1970 ( ! empty( $previous_sql_date ) )
1971 && ( '02' === substr( trim( $previous_sql_date ), -2 ) )
1972 && ( '01' === substr( trim( $dt ), -2 ) )
1973 );
1974 if ( $is_next_time_slot && ( ',' !== $previous_short_date_item ) ) {
1975 if ( '-' === $previous_short_date_item ) {
1976 array_pop( $short_dates_content_arr );
1977 }
1978 $short_dates_content_arr[] = '<span class="date_tire date_comma">, </span>'; // FixIn: 11.4.2.
1979 }
1980
1981 list( $formatted_date, $formatted_time ) = wpbc_get_date_in_correct_format( $dt );
1982
1983 $short_dates_content = '';
1984 $short_dates_content_sup = ''; // Times and booking resources.
1985
1986 if ( 'a' === $params['date_html_tag'] ) {
1987 $short_dates_content .= '<a href="javascript:void(0)" onclick="javascript:wpbc_ajx_click_on_dates_toggle(this);" ';
1988 } else {
1989 $short_dates_content .= '<' . $params['date_html_tag'];
1990 }
1991 $short_dates_content .= ' class="wpbc_label wpbc_label_booking_dates ' . $css_class_approved . '">';
1992
1993 $short_dates_content .= '<span>';
1994
1995 if ( $previous_formatted_date !== $formatted_date ) {
1996 $short_dates_content .= $formatted_date;
1997 $short_dates_content_sup .= '<sup class="field-booking-time">' . $formatted_time . '</sup>';
1998 } else {
1999 // same date (probaly it is one date) !
2000 if ( count( $short_dates_content_arr ) > 0 ) {
2001 // Unset tire: '-'.
2002 array_pop( $short_dates_content_arr );
2003 if ( ! empty( wp_strip_all_tags( $previous_short_dates_content_sup ) ) ) {
2004 $tag_closed_span_and_a = array_pop( $short_dates_content_arr );
2005 array_pop( $short_dates_content_arr ); // Unset time_sup.
2006 $short_dates_content_arr[] = $tag_closed_span_and_a; // FixIn: 11.4.2.
2007 }
2008 $short_dates_content_sup .= '<sup class="field-booking-time"> '
2009 . trim( wp_strip_all_tags( $previous_short_dates_content_sup ) )
2010 . ' - '
2011 . trim( $formatted_time )
2012 . '</sup>'; // FixIn: 11.4.2.
2013 }
2014 }
2015
2016 // BL.
2017 if (
2018 ( class_exists( 'wpdev_bk_biz_l' ) )
2019 && ( $params['show_child_resource_in_dates'] )
2020 && ( ! empty( $dates_type_id_arr[ $date_number ] ) )
2021 && ( isset( $booking_resources_arr[ $dates_type_id_arr[ $date_number ] ] ) )
2022 ){
2023
2024 $resource_title = ( isset( $booking_resources_arr[ $dates_type_id_arr[ $date_number ] ] ) )
2025 ? $booking_resources_arr[ $dates_type_id_arr[ $date_number ] ]['title']
2026 : __( 'Resource not exist', 'booking' );
2027 $resource_title = wpbc_lang( $resource_title );
2028
2029 if ( strlen( $resource_title ) > 19 ) {
2030 $resource_title = substr( $resource_title, 0, 13 ) . '...' . substr( $resource_title, - 3 );
2031 }
2032
2033 $short_dates_content_sup .= '<sup class="field-booking-time date_from_dif_type"> ' . $resource_title . '</sup>';
2034 }
2035
2036 $short_dates_content_arr[] = $short_dates_content;
2037 $short_dates_content_arr[] = $short_dates_content_sup;
2038 $short_dates_content_arr[] = '</span></' . $params['date_html_tag'] . '>';
2039
2040
2041
2042 $previous_short_dates_content_sup = $short_dates_content_sup;
2043 $previous_formatted_date = $formatted_date;
2044 $previous_sql_date = $dt;
2045 }
2046 $previous_short_date_item = $dt;
2047 $date_number++;
2048 }
2049
2050 $short_dates_content = implode( '', $short_dates_content_arr );
2051
2052 return $short_dates_content;
2053 }
2054
2055
2056 /**
2057 * Get Wide Dates showing data
2058 *
2059 * @param array $dates_arr - array of dates in sql string format
2060 * @param bool $is_approved - is approved (true) or pending (false)
2061 * @param array $dates_type_id_arr - array of $date->type_id from the dates SQL object
2062 * @param type $booking_resources_arr - array of booking resources objects
2063 *
2064 * @return string
2065 */
2066 function wpbc_get_formated_dates__wide( $dates_arr, $is_approved = false, $dates_type_id_arr = array(), $booking_resources_arr = array(), $attr = array() ) {
2067
2068 $defaults = array(
2069 'date_html_tag' => 'a',
2070 'show_child_resource_in_dates' => true,
2071 );
2072 $params = wp_parse_args( $attr, $defaults );
2073
2074 $wide_dates_arr = array();
2075
2076 $css_class_approved = ( $is_approved ) ? 'approved' : '';
2077
2078 foreach ( $dates_arr as $date_number => $sql_booking_date ) {
2079
2080 list( $formatted_date, $formatted_time ) = wpbc_get_date_in_correct_format( $sql_booking_date );
2081
2082 $wide_date = '';
2083 if ( 'a' === $params['date_html_tag'] ) {
2084 $wide_date .= '<a href="javascript:void(0)" onclick="javascript:wpbc_ajx_click_on_dates_toggle(this);" ';
2085 } else {
2086 $wide_date .= '<' . $params['date_html_tag'];
2087 }
2088 $wide_date .= ' class="wpbc_label wpbc_label_booking_dates ' . $css_class_approved . '">';
2089 $wide_date .= '<span>';
2090
2091 $wide_date .= $formatted_date;
2092 $wide_date .= '<sup class="field-booking-time">' . $formatted_time . '</sup>';
2093
2094 // BL
2095 if (
2096 ( class_exists( 'wpdev_bk_biz_l' ) )
2097 && ( $params['show_child_resource_in_dates'] )
2098 && ( '' != $dates_type_id_arr[ $date_number ] )
2099 && ( isset( $booking_resources_arr[ $dates_type_id_arr[ $date_number ] ] ) )
2100 ){
2101 $resource_title = ( isset( $booking_resources_arr[ $dates_type_id_arr[ $date_number ] ] ) )
2102 ? $booking_resources_arr[ $dates_type_id_arr[ $date_number ] ]['title']
2103 : __( 'Resource not exist', 'booking' );
2104 $resource_title = wpbc_lang( $resource_title );
2105
2106 if ( strlen( $resource_title ) > 19 ) {
2107 $resource_title = substr( $resource_title, 0, 13 ) . '...' . substr( $resource_title, - 3 );
2108 }
2109 $wide_date .= '<sup class="field-booking-time date_from_dif_type"> ' . $resource_title . '</sup>';
2110 }
2111
2112 $wide_date .= '</span></' . $params['date_html_tag'] . '>';
2113
2114 $wide_dates_arr[] = $wide_date;
2115 }
2116
2117 $wide_dates_content = implode( '<span class="date_tire date_comma">, </span>' , $wide_dates_arr );
2118
2119 return $wide_dates_content;
2120 }
2121
2122
2123 /**
2124 * Parse booking "data field" and get array
2125 *
2126 * @param string $data - "id^2~booking_type^Standard~status^Approved~dates^2019-09-18 00:00:00 - 2019-09-20 00:00:00 , 2019-09-18 00:00:00 (Standard-1) - 2019-09-20 00:00:00 (Standard-1)~modification_date^2019-09-05 10:50:04~cost^100.00~pay_status^156766972609.7~selected_short_timedates_hint^09/18/2019 - 09/20/2019~nights_number_hint^2~cost_hint^$75.00~name^John test~secondname^Smith~email^user@beta.com~phone^~visitors^4~children^~details^~term_and_condition^~user^Support A~wpbc_other_action^~rangetime^~other_email^~visitorsselector^~visitors_fee^~visitors_fee_hint^~trash^~remark^Approved by:John Smith (user@beta.com) [2019-09-11 09:30] Declined by:John Smith (user@beta.com) [2019-09-11 09:30]"
2127 * @param array $attr - array( 'r_separator' => '~', 'f_separator' => '^' )
2128 *
2129 * @return array - Array (
2130 [id] => 2
2131 [booking_type] => Standard
2132 [status] => Approved
2133 ... )
2134 */
2135 function wpbc_parse_booking_data_fields( $data , $attr = array() ){
2136
2137 $defaults = array(
2138 'r_separator' => '~' ,
2139 'f_separator' => '^' ,
2140 'resource_id' => '1' ,
2141 'system_fields' => array(
2142 'booking_id',
2143 'trash',
2144 //'sync_gid',
2145 'is_new',
2146 'status',
2147 'sort_date',
2148 'modification_date',
2149 'hash',
2150 'booking_type',
2151 'remark',
2152 'cost',
2153 'pay_status',
2154 'pay_request',
2155 'id',
2156 'approved'
2157 )
2158 );
2159 $attr = wp_parse_args( $attr, $defaults );
2160
2161 $data_arr = array();
2162
2163 if ( ! empty( $data ) ) {
2164
2165 $data = explode( $attr['r_separator'] , $data ); // ~
2166
2167 foreach ( $data as $data_rows ) {
2168
2169 $data_rows = explode( $attr['f_separator'] , $data_rows ); // ^
2170
2171 $data_field = array( 'type' => $data_rows[0], 'name' => $data_rows[1], 'value' => $data_rows[2] );
2172
2173 // remove checkboxes suffix []
2174 $data_field['name'] = str_replace( '[]', '', $data_field['name'] );
2175
2176 // remove booking resource ID suffix
2177 $data_field['name'] = substr( $data_field['name'], 0, - 1 * strlen( strval( $attr['resource_id'] ) ) );
2178
2179 // System fields - adjust fields with same name
2180 if ( in_array( $data_field['name'], $attr['system_fields'] ) ) {
2181 $data_field['name'] .= '_data';
2182 }
2183
2184 //Checkboxes
2185 if ( ( 'checkbox' == $data_field['type'] ) && ( empty( $data_field['value'] ) ) ) {
2186 continue;
2187 }
2188 if ( ( 'checkbox' == $data_field['type'] ) && ( ! is_array( $data_field['value'] ) ) ) {
2189 $data_field['value'] = str_replace( array( 'true', 'false' ), array(
2190 strtolower( __( 'Yes', 'booking' ) ),
2191 strtolower( __( 'No', 'booking' ) )
2192 ), $data_field['value'] );
2193 }
2194
2195 // Several items with same name - multi checkboxes
2196 if ( ! isset( $data_arr[ $data_field['name'] ] ) ) {
2197 $data_arr[ $data_field['name'] ] = $data_field['value'];
2198 } else {
2199 if ( is_array( $data_arr[ $data_field['name'] ] ) ) {
2200 $data_arr[ $data_field['name'] ][] = $data_field['value'];
2201 } else {
2202 $data_arr[ $data_field['name'] ] = array( $data_arr[ $data_field['name'] ], $data_field['value'] );
2203 }
2204 }
2205
2206 }
2207 }
2208
2209 foreach ( $data_arr as $key => $value ) {
2210
2211 // Multi checkboxes: [9] => checkbox^my_multi_checkbx4[]^1 [10] => checkbox^my_multi_checkbx4[]^ [11] => checkbox^my_multi_checkbx4[]^3
2212 if ( is_array( $value ) ) {
2213 $value = implode( ',', $value );
2214 $data_arr[$key] = $value;
2215 }
2216 }
2217
2218 return $data_arr;
2219 }
2220
2221
2222 /**
2223 * Add system fields to Booking fields array and get final array of fields
2224 * @param array $booking_data_arr Original array of form fields from DB
2225 Array (
2226 [selected_short_dates_hint] => March 5, 2023
2227 [days_number_hint] => 1
2228 [cost_hint] => &amp;#36;95
2229 [rangetime] => 10:00 AM - 12:00 PM
2230 [name] => test
2231 [email] => test@wpbookingcalendar.com
2232 ...
2233 )
2234
2235 * @param array $booking_system_arr array of system fields from DB
2236 Array ( [booking_id] => 188
2237 [trash] => 0
2238 ...
2239 [cost] => 95.00
2240 [pay_status] => 165036591118.88
2241 [pay_request] => 0
2242 [id] => 188
2243 [approved] => 0
2244 )
2245
2246 * @param array $system_keys_arr system fields keys that need to be added, like this:
2247 Array ( booking_id, trash, sync_gid, is_new, status
2248 , sort_date, modification_date, hash, booking_type
2249 , remark, cost, pay_status, pay_request, id, approved )
2250
2251 * @return array array of form fields with system fields
2252 */
2253 function wpbc_add_system_booking_data_fields( $booking_data_arr, $booking_system_arr, $system_keys_arr ){
2254
2255 foreach ( $system_keys_arr as $key ) {
2256
2257 if (
2258 ( ! isset( $booking_system_arr[ $key ] ) )
2259 || ( is_null( $booking_system_arr[ $key ] ) )
2260 ) {
2261 $booking_system_arr[ $key ] = ''; //Some fields, like remark or booking_options can be null, so we define them as ''
2262 }
2263
2264 if ( isset( $booking_system_arr[ $key ] ) ) {
2265
2266 if ( ! isset( $booking_data_arr[ $key ] ) ) {
2267 $booking_data_arr[ $key ] = maybe_unserialize( $booking_system_arr[ $key ] );
2268 } else {
2269 $booking_data_arr[ $key . '_system' ] = maybe_unserialize( $booking_system_arr[ $key ] );
2270 }
2271 }
2272
2273 }
2274 return $booking_data_arr;
2275 }
2276
2277
2278 /**
2279 * Parse booking form fields format - for example: time fields in specific format
2280 * @param $data_arr
2281 *
2282 * @return array
2283 */
2284 function wpbc_parse_booking_data_fields_formats( $data_arr ){
2285
2286 foreach ( $data_arr as $key => $value ) {
2287
2288 if ( 'rangetime' == $key ) {
2289 $data_arr[$key] = wpbc_time_slot_in_format( $value );
2290 $data_arr[ $key . '_in_24_hour' ] = $value; // FixIn: 10.0.0.52.
2291 }
2292
2293 if ( in_array( $key, array( 'starttime', 'endtime' ) ) ) {
2294 $data_arr[$key] = wpbc_time_in_format( $value );
2295 $data_arr[ $key . '_in_24_hour' ] = $value; // FixIn: 10.0.0.52.
2296 }
2297
2298 if ( in_array( $key, array( 'modification_date', 'creation_date' ) ) ) {
2299
2300 //$data_arr[$key] = wpbc_get_dates_comma_string_localized( $value );
2301
2302
2303 // This date $values in GMT date/Time format. So we need to switch to WordPress locale with TIME sum of actual GMT date/time value + shift of timezone from WordPress.
2304 $is_add_wp_timezone = true;
2305 $its_for_default_datetime_format = '';
2306 $data_arr[ $key ] = wpbc_datetime_localized( $value, $its_for_default_datetime_format, $is_add_wp_timezone );
2307 $data_arr[ $key . '_in_24_hour' ] = $value; // FixIn: 10.0.0.52.
2308 }
2309
2310 if ( ( 'hash' === $key ) && ( empty( $value ) ) ) { //FixIn: 9.2.3.4 // FixIn: 9.4.3.10.
2311 // Update booking Hash if it was empty
2312 wpbc_hash__update_booking_hash( $data_arr['id'], $data_arr['booking_type'] );
2313 // Get new booking hash
2314 $hash__arr = wpbc_hash__get_booking_hash__resource_id( $data_arr['id'] );
2315 if ( ! empty( $hash__arr ) ) {
2316 $data_arr[ $key ] = $hash__arr[0];
2317 }
2318 }
2319 }
2320 return $data_arr;
2321 }
2322
2323
2324 /**
2325 * Get pure "Content of booking fields data" with shortcodes inside.
2326 * Can depend on booking resource (BM) or resource owner (MU).
2327 * Now also supports BFB DB resolver (published/preview-aware).
2328 *
2329 * @param int $resource_id
2330 * @param string $custom_booking_form_name Optional. Force this custom form if possible.
2331 *
2332 * @return string
2333 */
2334 function wpbc_get_content_booking_form_show( $resource_id, $custom_booking_form_name = '' ) { // FixIn: 9.4.3.12.
2335
2336 static $wpbc__form_show_cache = array();
2337
2338 $resource_id = (int) $resource_id;
2339 $custom_booking_form_name = (string) $custom_booking_form_name;
2340
2341 if ( - 1 === $resource_id ) {
2342 if ( function_exists( 'get__default_type' ) ) {
2343 $resource_id = (int) get__default_type();
2344 } else {
2345 $resource_id = 1;
2346 }
2347 }
2348
2349 // ------------------------------------------------------------
2350 // Determine a stable form slug early (avoid undefined var).
2351 // This is used for cache key and for resolver path.
2352 // ------------------------------------------------------------
2353 $my_booking_form_name = ( '' !== $custom_booking_form_name ) ? $custom_booking_form_name : 'standard';
2354
2355 // Preview-aware context (optional; usually "published" in Booking Listing).
2356 $ctx = array();
2357 if ( function_exists( 'wpbc_get_request_form_context' ) ) {
2358 $ctx = wpbc_get_request_form_context();
2359 }
2360 $form_status = ( isset( $ctx['form_status'] ) ) ? sanitize_key( $ctx['form_status'] ) : 'published';
2361 if ( in_array( $form_status, array( 'publish', 'published' ), true ) ) {
2362 $form_status = 'published';
2363 }
2364 if ( 'preview' !== $form_status ) {
2365 $form_status = 'published';
2366 }
2367
2368 // Cache key (important: this function is called per booking row).
2369 $cache_key = get_locale() . '|' . $form_status . '|' . $resource_id . '|' . $my_booking_form_name;
2370 if ( isset( $wpbc__form_show_cache[ $cache_key ] ) ) {
2371 return $wpbc__form_show_cache[ $cache_key ];
2372 }
2373
2374 if ( '' === $custom_booking_form_name ) {
2375 $default_form_name = apply_bk_filter( 'wpbc_get_default_custom_form', 'standard', $resource_id );
2376 if ( ! empty( $default_form_name ) ) {
2377 $my_booking_form_name = $default_form_name;
2378 }
2379 }
2380
2381 $booking_form_show = '';
2382
2383 if ( class_exists( 'WPBC_FE_Form_Source_Resolver' ) && class_exists( 'WPBC_BFB_Form_Loader' ) ) {
2384
2385 $req = array(
2386 'resource_id' => (int) $resource_id,
2387 'form_slug' => (string) $my_booking_form_name,
2388 'form_status' => $form_status,
2389 'custom_params' => array(),
2390 'ctx' => ( is_array( $ctx ) ? $ctx : array() ),
2391 );
2392
2393 $resolved = WPBC_FE_Form_Source_Resolver::resolve( $req );
2394
2395 // If preview requested but not found, try published as fallback.
2396 if ( ( empty( $resolved['engine'] ) || ( 'bfb_db' !== $resolved['engine'] ) ) && ( 'preview' === $form_status ) ) {
2397 $req['form_status'] = 'published';
2398 $resolved = WPBC_FE_Form_Source_Resolver::resolve( $req );
2399 }
2400
2401 if ( ! empty( $resolved['engine'] ) && ( 'bfb_db' === $resolved['engine'] ) ) {
2402
2403 $bfb_loader_args = array();
2404 if ( ! empty( $resolved['bfb_loader_args'] ) && is_array( $resolved['bfb_loader_args'] ) ) {
2405 $bfb_loader_args = $resolved['bfb_loader_args'];
2406 }
2407
2408 // We need "content_form" template for booking fields output.
2409 $bfb_loader_args['return'] = 'content_form';
2410
2411 $bfb_pair = wpbc_bfb_get_booking_form_pair( $bfb_loader_args );
2412
2413 $content_form = '';
2414 if ( is_array( $bfb_pair ) && isset( $bfb_pair['content'] ) ) {
2415 $content_form = (string) $bfb_pair['content'];
2416 }
2417
2418 if ( '' !== trim( $content_form ) ) {
2419 $booking_form_show = wpbc_bf__replace_custom_html_shortcodes( $content_form );
2420 }
2421 }
2422 }
2423
2424 // ------------------------------------------------------------
2425 // Language + cleanup (keep old behavior).
2426 // ------------------------------------------------------------
2427 $booking_form_show = wpbc_lang( $booking_form_show );
2428
2429 $search = array( "'(<br[ ]?[/]?>)+'si", "'(<[/]?p[ ]?>)+'si" );
2430 $replace = array( "&nbsp;&nbsp;", " &nbsp; ", " &nbsp; " );
2431 $booking_form_show = preg_replace( $search, $replace, $booking_form_show );
2432
2433 // Store cache by final slug (slug may have changed in BM branch).
2434 $final_cache_key = get_locale() . '|' . $form_status . '|' . $resource_id . '|' . $my_booking_form_name;
2435 $wpbc__form_show_cache[ $final_cache_key ] = $booking_form_show;
2436
2437 return $booking_form_show;
2438 }
2439
2440
2441
2442 /**
2443 * Get parsed "Content of booking fields data" - Shortcodes replaced by Values
2444 *
2445 * @param array $booking_data_arr
2446 * @param string $booking_form_show
2447 *
2448 * @return string
2449 */
2450 function wpbc_get_parsed_content_booking_form_show( $booking_data_arr, $booking_form_show ){
2451
2452 foreach ( $booking_data_arr as $key_param => $value_param ) {
2453 if ( ( gettype ( $value_param ) != 'array' )
2454 && ( gettype ( $value_param ) != 'object' )
2455 ) {
2456 $booking_form_show = str_replace( '['. $key_param .']', $value_param ,$booking_form_show);
2457 }
2458 }
2459 // Remove all shortcodes, which have not replaced early.
2460 $booking_form_show = preg_replace ('/[\s]{0,}\[[a-zA-Z0-9.,-_]{0,}\][\s]{0,}/', '', $booking_form_show);
2461
2462 $booking_form_show = str_replace( "&amp;", '&', $booking_form_show );
2463
2464 return $booking_form_show;
2465 }
2466
2467 // </editor-fold>
2468
2469
2470 // <editor-fold defaultstate="collapsed" desc=" F u n c t i o n s f o r C l e a n i ng s " >
2471
2472 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2473 // Escaping
2474 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2475
2476 /**
2477 * Escaping for inline JavaScript.
2478 * Based on WordPress esc_js()
2479 * plus removing \n in the code
2480 * and back converting escaped single quotes from \' to '
2481 *
2482 * This function has to be used in the code marked with double quote symbols, not single.
2483 * Example: onclick="javascript:<?php
2484 // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
2485 echo wpbc_esc_js( $item_params['action'] ); ?>"
2486 *
2487 * @param $text
2488 *
2489 * @return string
2490 */
2491 function wpbc_esc_js( $text ) {
2492
2493 $text = str_replace( "\n", '', $text ); // removing \n in the code
2494
2495 //$safe_text = esc_js( $text ); // js
2496
2497 // This code get from esc_js() and modified for correct working with (' symbols) in translations
2498 $safe_text = wp_check_invalid_utf8( $text );
2499 $safe_text = _wp_specialchars( $safe_text, ENT_COMPAT );
2500 $safe_text = preg_replace( '/&#(x)?0*(?(1)27|39);?/i', "\'", stripslashes( $safe_text ) );
2501 $safe_text = str_replace( "\r", '', $safe_text );
2502 $safe_text = str_replace( "\n", '\\n', addslashes( $safe_text ) );
2503
2504 $safe_text = str_replace( "\'", "'", $safe_text ); // back converting escaped single quotes from \' to '
2505 $safe_text = str_replace( "\\\'", "\'", $safe_text ); // back converting escaped single quotes from \' to '
2506
2507 return $safe_text;
2508 }
2509
2510
2511 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2512 // DB
2513 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2514
2515 /**
2516 * Check $value for injections. Basically can be used in Requests params checking.
2517 *
2518 * @param type $value
2519 *
2520 * @return type
2521 */
2522 function wpbc_esc_clean_parameter( $value ) {
2523
2524 $value = preg_replace( '/<[^>]*>/', '', $value ); // clean any tags
2525 $value = str_replace( '<', ' ', $value );
2526 $value = str_replace( '>', ' ', $value );
2527 $value = wp_strip_all_tags( $value ); // Strip HTML and PHP tags from a string
2528
2529 // Clean SQL injection
2530 $value = esc_sql( $value );
2531 $value = esc_textarea( $value ); // FixIn: 7.1.1.2.
2532
2533 return $value;
2534 }
2535
2536
2537 function wpbc_esc_sql_like( $value_trimmed ) {
2538
2539 // check here https://code.tutsplus.com/articles/data-sanitization-and-validation-with-wordpress--wp-25536
2540
2541 global $wpdb;
2542 if ( method_exists( $wpdb ,'esc_like' ) )
2543 return $wpdb->esc_like( $value_trimmed ); // Its require minimum WP 4.0.0
2544 else
2545 return addcslashes( $value_trimmed, '_%\\' ); // Direct implementation from $wpdb->esc_like(
2546 }
2547
2548
2549 /**
2550 * Clean user string for using in SQL LIKE statement - append to LIKE sql
2551 *
2552 * @param string $value - to clean
2553 *
2554 * @return string - escaped
2555 * Exmaple:
2556 * $search_escaped_like_title = wpbc_esc_clean_like_string_for_append_in_sql_for_db( $input_var );
2557 *
2558 * $where_sql = " WHERE title LIKE ". $search_escaped_like_title ." ";
2559 */
2560 function wpbc_esc_clean_like_string_for_append_in_sql_for_db( $value ) {
2561
2562 // check here https://code.tutsplus.com/articles/data-sanitization-and-validation-with-wordpress--wp-25536
2563
2564 global $wpdb;
2565
2566 $value_trimmed = trim( stripslashes( $value ) );
2567
2568 $wild = '%';
2569 $like = $wild . wpbc_esc_sql_like( $value_trimmed ) . $wild;
2570
2571 /* phpcs:ignore WordPress.DB.PreparedSQLPlaceholders.QuotedSimplePlaceholder */
2572 $sql = $wpdb->prepare( "'%s'", $like );
2573
2574 return $sql;
2575
2576
2577 /* Help:
2578 * First half of escaping for LIKE special characters % and _ before preparing for MySQL.
2579 * Use this only before wpdb::prepare() or esc_sql(). Reversing the order is very bad for security.
2580 *
2581 * Example Prepared Statement:
2582 *
2583 * $wild = '%';
2584 * $find = 'only 43% of planets';
2585 * $like = $wild . wpbc_esc_sql_like( $find ) . $wild;
2586 * $sql = $wpdb->prepare( "SELECT * FROM $wpdb->posts WHERE post_content LIKE '%s'", $like );
2587 *
2588 * Example Escape Chain:
2589 *
2590 * $sql = esc_sql( wpbc_esc_sql_like( $input ) );
2591 */
2592
2593 }
2594
2595
2596 /**
2597 * Clean string for using in SQL LIKE requests inside single quotes: WHERE title LIKE '%". $escaped_search_title ."%'
2598 * Replaced _ to \_ % to \% \ to \\
2599 *
2600 * @param string $value - to clean
2601 *
2602 * @return string - escaped
2603 * Exmaple:
2604 * $search_escaped_like_title = wpbc_esc_clean_like_string_for_db( $input_var );
2605 *
2606 * $where_sql = " WHERE title LIKE '%". $search_escaped_like_title ."%' ";
2607 *
2608 * Important! Use SINGLE quotes after in SQL query: LIKE '%".$data."%'
2609 */
2610 function wpbc_esc_clean_like_string_for_db( $value ){
2611
2612 // check here https://code.tutsplus.com/articles/data-sanitization-and-validation-with-wordpress--wp-25536
2613
2614 global $wpdb;
2615
2616 $value_trimmed = trim( stripslashes( $value ) );
2617
2618 $value_trimmed = wpbc_esc_sql_like( $value_trimmed );
2619
2620 /* phpcs:ignore WordPress.DB.PreparedSQLPlaceholders.QuotedSimplePlaceholder */
2621 $value = trim( $wpdb->prepare( "'%s'", $value_trimmed ) , "'" );
2622
2623 return $value;
2624
2625 /* Help:
2626 * First half of escaping for LIKE special characters % and _ before preparing for MySQL.
2627 * Use this only before wpdb::prepare() or esc_sql(). Reversing the order is very bad for security.
2628 *
2629 * Example Prepared Statement:
2630 *
2631 * $wild = '%';
2632 * $find = 'only 43% of planets';
2633 * $like = $wild . wpbc_esc_sql_like( $find ) . $wild;
2634 * $sql = $wpdb->prepare( "SELECT * FROM $wpdb->posts WHERE post_content LIKE '%s'", $like );
2635 *
2636 * Example Escape Chain:
2637 *
2638 * $sql = esc_sql( wpbc_esc_sql_like( $input ) );
2639 */
2640 }
2641
2642
2643 // </editor-fold>
2644
2645
2646 // <editor-fold defaultstate="collapsed" desc=" D B " >
2647
2648 /***
2649 * Get list of DB of this plugin
2650 * @return array
2651 */
2652 function wpbc_get_db_names(){
2653
2654 global $wpdb;
2655
2656 $db_names = array(
2657 'bookings' => $wpdb->prefix . 'booking',
2658 'dates' => $wpdb->prefix . 'bookingdates',
2659 'resources' => $wpdb->prefix . 'bookingtypes',
2660 'resources_meta' => $wpdb->prefix . 'booking_types_meta',
2661 'seasons' => $wpdb->prefix . 'booking_seasons',
2662 'coupons' => $wpdb->prefix . 'booking_coupons'
2663 );
2664
2665 return $db_names;
2666 }
2667
2668 // </editor-fold>
2669
2670
2671 // <editor-fold defaultstate="collapsed" desc=" E r r o r s H a n d l i n g " >
2672
2673 /**
2674 * PHP Fatal Error! Display expanded error info at Booking Listing page
2675 *
2676 * @param $message
2677 * @param $error
2678 *
2679 * @return mixed|string
2680 */
2681 function wpbc_php_error_message( $message, $error ) {
2682
2683 // Check to show this error, only from Booking Listing page, checking secure parameters from wpbc_ajx_booking_listing in ..{Booking Calendar Folder}/includes/page-bookings/_src/ajx_booking_listing.js
2684 // phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.NonceVerification.Missing
2685 if ( ! ( ! isset( $_POST['search_params'] ) || empty( $_POST['search_params'] ) ) ) {
2686 // Security ----------------------------------------------------------------------------------------------- // in Ajax Post: 'nonce': wpbc_ajx_booking_listing.get_secure_param( 'nonce' ),
2687 $action_name = 'wpbc_ajx_booking_listing_ajx' . '_wpbcnonce';
2688 $nonce_post_key = 'nonce';
2689 // $result_check = check_ajax_referer( $action_name, $nonce_post_key );
2690 // phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.NonceVerification.Missing
2691 if ( isset( $_REQUEST[ $nonce_post_key ] ) ) {
2692 // phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.NonceVerification.Missing, WordPress.Security.ValidatedSanitizedInput.MissingUnslash, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
2693 $nonce_request = $_REQUEST[ $nonce_post_key ];
2694
2695 $result_verify_nonce = wp_verify_nonce( $nonce_request, $action_name );
2696
2697 if ( false !== $result_verify_nonce ) {
2698 if ( ( ! empty( $error ) ) && ( ! empty( $error['message'] ) ) ) {
2699 $message .= '<br>' . $error['message'];
2700 }
2701 }
2702 }
2703 }
2704
2705 return $message;
2706 }
2707 add_filter( 'wp_php_error_message', 'wpbc_php_error_message', 2 , 10 );
2708
2709
2710 /**
2711 * Nonce Error! Error Handing for not passed nonce, in booking Listing page.
2712 * Probably nonce was expired (more than 24 hours)
2713 *
2714 * @param $action
2715 * @param $result - 1 Good ( 0-12 hours ago ) , 2 Good ( 12-24 hours ago ) , false - Error ( > 24 hours - nonce is invalid )
2716 */
2717 function wpbc_check_ajax_referer__for_booking_listing( $action, $result ){
2718 if (
2719 ( false === $result )
2720 && ( 'wpbc_ajx_booking_listing_ajx' . '_wpbcnonce' === $action )
2721 && ( wp_doing_ajax() )
2722 ) {
2723 die( '<strong>Error!</strong> Probably nonce for this page has been expired. Please <a href="javascript:void(0)" onclick="javascript:location.reload();">reload the page</a>.' );
2724 }
2725 }
2726 add_action( 'check_ajax_referer', 'wpbc_check_ajax_referer__for_booking_listing', 2, 10 );
2727 // </editor-fold>
2728