PluginProbe
Booking Calendar / 10.11.2
Booking Calendar v10.11.2
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 10.11.2, at includes/page-bookings/bookings__sql.php

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