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

2,550 lines 110.5 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_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['view_mode']) ) && ( $_REQUEST['view_mode']== '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_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 $short_dates_content = wpbc_get_formated_dates__short( $booking->short_dates, (boolean) $booking->approved, $booking->short_dates_child_id, $resources_arr );
1782 $wide_dates_content = wpbc_get_formated_dates__wide( $booking->dates, (boolean) $booking->approved, $booking->child_id, $resources_arr );
1783
1784 //------------------------------------------------------------------------------------------------------
1785 // Payment Status
1786 //------------------------------------------------------------------------------------------------------
1787 if ( 1 ) {
1788 $booking_data_arr['is_paid'] = 0; // 0 | 1
1789 $booking_data_arr['pay_print_status'] = ''; // "Unknown" | "Stripe_v3:OK"
1790 // $booking_data_arr['pay_status'] // "165458416073.66" | "Stripe_v3:OK" | "PayPal:Ok"
1791
1792 if ( class_exists( 'wpdev_bk_biz_s' ) ) {
1793
1794 if ( wpbc_is_payment_status_ok( trim( $booking_data_arr['pay_status'] ) ) ) {
1795 $booking_data_arr['is_paid'] = 1;
1796 }
1797
1798 $payment_status_titles = get_payment_status_titles();
1799
1800 $current_payment_status_title = array_search( $booking_data_arr['pay_status'], $payment_status_titles );
1801
1802 if ( $current_payment_status_title === false ) {
1803 $current_payment_status_title = $booking_data_arr['pay_status'];
1804 }
1805
1806 if ( $booking_data_arr['is_paid'] ) {
1807 $booking_data_arr['pay_print_status'] = $booking_data_arr['pay_status'];
1808 if ( $current_payment_status_title == 'Completed' ) {
1809 $booking_data_arr['pay_print_status'] = $current_payment_status_title;
1810 }
1811 } else if ( ( is_numeric( $booking_data_arr['pay_status'] ) ) || ( $booking_data_arr['pay_status'] == '' ) ) {
1812 $booking_data_arr['pay_print_status'] = __( 'Unknown', 'booking' );
1813 } else {
1814 $booking_data_arr['pay_print_status'] = $current_payment_status_title;
1815 }
1816 ////////////////////////////////////////////////////////////////////////////////////////////////////
1817
1818 if ( $booking_data_arr['pay_print_status'] == 'Completed' ) { // FixIn: 8.4.7.11.
1819 $booking_data_arr['pay_print_status'] = __( 'Completed', 'booking' );
1820 }
1821 $real_payment_css = empty( $booking_data_arr['pay_status'] ) ? $current_payment_status_title : $booking_data_arr['pay_status']; // FixIn: 8.7.7.13.
1822 $css_payment_label = 'wpbc_label_payment_status_' . wpbc_check_payment_status( $real_payment_css ); // 'success' | 'pending' | 'unknown' | 'error' // FixIn: 8.7.7.13.
1823
1824 if ( $booking_data_arr['is_paid'] ) {
1825 $css_payment_label .= ' wpbc_label_payment_status_success';
1826 }
1827 $payment_label_template = '<span class="wpbc_label wpbc_label_payment_status ' . $css_payment_label . '">'
1828 . '<span style="font-size:07px;padding: 0 1em 0 0;line-height: 2em;">'
1829 . __( 'Payment', 'booking' )
1830 . '</span> '
1831 . '<span>'
1832 . $booking_data_arr['pay_print_status']
1833 . '</span> '
1834 . '</span>';
1835 } else {
1836 $payment_label_template = '';
1837 }
1838 }
1839
1840 //------------------------------------------------------------------------------------------------------
1841 // Currency
1842 //------------------------------------------------------------------------------------------------------
1843 if ( class_exists( 'wpdev_bk_biz_s' ) ) {
1844 $currency_symbol = wpbc_get_currency_symbol_for_user( $resource_id );
1845 $booking_data_arr['currency_symbol'] = $currency_symbol;
1846 }
1847
1848 //------------------------------------------------------------------------------------------------------
1849 // Add some fields to [ 'parsed_fields' ]
1850 //------------------------------------------------------------------------------------------------------
1851 $booking_data_arr['resource_title'] = $resource_title;
1852 $booking_data_arr['resource_id'] = $resource_id;
1853 $booking_data_arr['resource_owner_user'] = $resource_owner_user;
1854 //$booking_data_arr['short_dates_content'] = $short_dates_content;
1855 //$booking_data_arr['wide_dates_content'] = $wide_dates_content;
1856
1857 //------------------------------------------------------------------------------------------------------
1858 // Form Show - "Content of booking fields data" form
1859 //------------------------------------------------------------------------------------------------------
1860
1861 $custom_booking_form_name = ( ! empty( $booking_data_arr['wpbc_custom_booking_form'] ) ) ? $booking_data_arr['wpbc_custom_booking_form'] : ''; // FixIn: 9.4.3.12.
1862 $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; ...
1863 $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; ...
1864
1865 //------------------------------------------------------------------------------------------------------
1866 // Google Calendar link
1867 //------------------------------------------------------------------------------------------------------
1868 $booking_data_arr['google_calendar_link'] = wpbc_booking_do_action__get_google_calendar_link( array(
1869 'form_data' => $booking_data_arr,
1870 'form_show' => $parsed_form_show, //wp_strip_all_tags( $parsed_form_show ),
1871 'dates_short' => $booking->short_dates
1872 ) );
1873
1874 // =====================================================================================================
1875 $bookings_arr[ $booking_id ]->parsed_fields = $booking_data_arr;
1876
1877
1878 // =====================================================================================================
1879 $bookings_arr[ $booking_id ]->templates = array(
1880 'form_show' => $parsed_form_show,
1881 'form_show_nohtml' => wp_strip_all_tags( $parsed_form_show ),
1882 'short_dates_content' => $short_dates_content,
1883 'wide_dates_content' => $wide_dates_content,
1884 'payment_label_template' => $payment_label_template
1885 );
1886 }
1887
1888 return $bookings_arr;
1889 }
1890
1891
1892 /**
1893 * Get SHORT Dates showing data
1894 *
1895 * @param array $short_dates_arr - Array of dates
1896 * @param bool $is_approved - is dates approved or not
1897 * @param type $dates_type_id_arr
1898 * @param type $booking_resources_arr
1899 *
1900 * @return string
1901 */
1902 function wpbc_get_formated_dates__short( $short_dates_arr, $is_approved = false, $dates_type_id_arr = array() , $booking_resources_arr = array() ){
1903
1904 $css_class_approved = ( $is_approved ) ? 'approved' : '';
1905 $short_dates_content = '';
1906 $date_number = 0;
1907
1908 foreach ( $short_dates_arr as $dt ) {
1909
1910 if ( $dt == '-' ) {
1911
1912 $short_dates_content .= '<span class="date_tire"> - </span>';
1913
1914 } elseif ( $dt == ',' ) {
1915
1916 $short_dates_content .= '<span class="date_tire">, </span>';
1917
1918 } else {
1919
1920 list( $formatted_date, $formatted_time ) = wpbc_get_date_in_correct_format( $dt );
1921
1922 $short_dates_content .= '<a href="javascript:void(0)" onclick="javascript:wpbc_ajx_click_on_dates_toggle(this);" class="wpbc_label wpbc_label_booking_dates ' . $css_class_approved . '"><span>';
1923 $short_dates_content .= $formatted_date;
1924 $short_dates_content .= '<sup class="field-booking-time">' . $formatted_time . '</sup>';
1925
1926 // BL
1927 if (
1928 ( class_exists( 'wpdev_bk_biz_l' ) )
1929 && ( ! empty( $dates_type_id_arr[ $date_number ] ) )
1930 && ( isset( $booking_resources_arr[ $dates_type_id_arr[ $date_number ] ] ) )
1931 ){
1932
1933 $resource_title = ( isset( $booking_resources_arr[ $dates_type_id_arr[ $date_number ] ] ) )
1934 ? $booking_resources_arr[ $dates_type_id_arr[ $date_number ] ]['title']
1935 : __( 'Resource not exist', 'booking' );
1936 $resource_title = wpbc_lang( $resource_title );
1937
1938 if ( strlen( $resource_title ) > 19 ) {
1939 $resource_title = substr( $resource_title, 0, 13 ) . '...' . substr( $resource_title, - 3 );
1940 }
1941
1942 $short_dates_content .= '<sup class="field-booking-time date_from_dif_type"> ' . $resource_title . '</sup>';
1943 }
1944
1945 $short_dates_content .= '</span></a>';
1946 }
1947 $date_number++;
1948 }
1949
1950 return $short_dates_content;
1951 }
1952
1953
1954 /**
1955 * Get Wide Dates showing data
1956 *
1957 * @param array $dates_arr - array of dates in sql string format
1958 * @param bool $is_approved - is approved (true) or pending (false)
1959 * @param array $dates_type_id_arr - array of $date->type_id from the dates SQL object
1960 * @param type $booking_resources_arr - array of booking resources objects
1961 *
1962 * @return string
1963 */
1964 function wpbc_get_formated_dates__wide( $dates_arr, $is_approved = false, $dates_type_id_arr = array(), $booking_resources_arr = array() ){
1965
1966 $wide_dates_arr = array();
1967
1968 $css_class_approved = ( $is_approved ) ? 'approved' : '';
1969
1970 foreach ( $dates_arr as $date_number => $sql_booking_date ) {
1971
1972 list( $formatted_date, $formatted_time ) = wpbc_get_date_in_correct_format( $sql_booking_date );
1973
1974 $wide_date = '<a href="javascript:void(0)" onclick="javascript:wpbc_ajx_click_on_dates_toggle(this);" class="wpbc_label wpbc_label_booking_dates ' . $css_class_approved . '"><span>';
1975 $wide_date .= $formatted_date;
1976 $wide_date .= '<sup class="field-booking-time">' . $formatted_time . '</sup>';
1977
1978 // BL
1979 if (
1980 ( class_exists( 'wpdev_bk_biz_l' ) )
1981 && ( '' != $dates_type_id_arr[ $date_number ] )
1982 && ( isset( $booking_resources_arr[ $dates_type_id_arr[ $date_number ] ] ) )
1983 ){
1984 $resource_title = ( isset( $booking_resources_arr[ $dates_type_id_arr[ $date_number ] ] ) )
1985 ? $booking_resources_arr[ $dates_type_id_arr[ $date_number ] ]['title']
1986 : __( 'Resource not exist', 'booking' );
1987 $resource_title = wpbc_lang( $resource_title );
1988
1989 if ( strlen( $resource_title ) > 19 ) {
1990 $resource_title = substr( $resource_title, 0, 13 ) . '...' . substr( $resource_title, - 3 );
1991 }
1992 $wide_date .= '<sup class="field-booking-time date_from_dif_type"> ' . $resource_title . '</sup>';
1993 }
1994
1995 $wide_date .= '</span></a>';
1996
1997 $wide_dates_arr[] = $wide_date;
1998 }
1999
2000 $wide_dates_content = implode( '<span class="date_tire">, </span>' , $wide_dates_arr );
2001
2002 return $wide_dates_content;
2003 }
2004
2005
2006 /**
2007 * Parse booking "data field" and get array
2008 *
2009 * @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]"
2010 * @param array $attr - array( 'r_separator' => '~', 'f_separator' => '^' )
2011 *
2012 * @return array - Array (
2013 [id] => 2
2014 [booking_type] => Standard
2015 [status] => Approved
2016 ... )
2017 */
2018 function wpbc_parse_booking_data_fields( $data , $attr = array() ){
2019
2020 $defaults = array(
2021 'r_separator' => '~' ,
2022 'f_separator' => '^' ,
2023 'resource_id' => '1' ,
2024 'system_fields' => array(
2025 'booking_id',
2026 'trash',
2027 //'sync_gid',
2028 'is_new',
2029 'status',
2030 'sort_date',
2031 'modification_date',
2032 'hash',
2033 'booking_type',
2034 'remark',
2035 'cost',
2036 'pay_status',
2037 'pay_request',
2038 'id',
2039 'approved'
2040 )
2041 );
2042 $attr = wp_parse_args( $attr, $defaults );
2043
2044 $data_arr = array();
2045
2046 if ( ! empty( $data ) ) {
2047
2048 $data = explode( $attr['r_separator'] , $data ); // ~
2049
2050 foreach ( $data as $data_rows ) {
2051
2052 $data_rows = explode( $attr['f_separator'] , $data_rows ); // ^
2053
2054 $data_field = array( 'type' => $data_rows[0], 'name' => $data_rows[1], 'value' => $data_rows[2] );
2055
2056 // remove checkboxes suffix []
2057 $data_field['name'] = str_replace( '[]', '', $data_field['name'] );
2058
2059 // remove booking resource ID suffix
2060 $data_field['name'] = substr( $data_field['name'], 0, - 1 * strlen( strval( $attr['resource_id'] ) ) );
2061
2062 // System fields - adjust fields with same name
2063 if ( in_array( $data_field['name'], $attr['system_fields'] ) ) {
2064 $data_field['name'] .= '_data';
2065 }
2066
2067 //Checkboxes
2068 if ( ( 'checkbox' == $data_field['type'] ) && ( empty( $data_field['value'] ) ) ) {
2069 continue;
2070 }
2071 if ( ( 'checkbox' == $data_field['type'] ) && ( ! is_array( $data_field['value'] ) ) ) {
2072 $data_field['value'] = str_replace( array( 'true', 'false' ), array(
2073 strtolower( __( 'Yes', 'booking' ) ),
2074 strtolower( __( 'No', 'booking' ) )
2075 ), $data_field['value'] );
2076 }
2077
2078 // Several items with same name - multi checkboxes
2079 if ( ! isset( $data_arr[ $data_field['name'] ] ) ) {
2080 $data_arr[ $data_field['name'] ] = $data_field['value'];
2081 } else {
2082 if ( is_array( $data_arr[ $data_field['name'] ] ) ) {
2083 $data_arr[ $data_field['name'] ][] = $data_field['value'];
2084 } else {
2085 $data_arr[ $data_field['name'] ] = array( $data_arr[ $data_field['name'] ], $data_field['value'] );
2086 }
2087 }
2088
2089 }
2090 }
2091
2092 foreach ( $data_arr as $key => $value ) {
2093
2094 // Multi checkboxes: [9] => checkbox^my_multi_checkbx4[]^1 [10] => checkbox^my_multi_checkbx4[]^ [11] => checkbox^my_multi_checkbx4[]^3
2095 if ( is_array( $value ) ) {
2096 $value = implode( ',', $value );
2097 $data_arr[$key] = $value;
2098 }
2099 }
2100
2101 return $data_arr;
2102 }
2103
2104
2105 /**
2106 * Add system fields to Booking fields array and get final array of fields
2107 * @param array $booking_data_arr Original array of form fields from DB
2108 Array (
2109 [selected_short_dates_hint] => March 5, 2023
2110 [days_number_hint] => 1
2111 [cost_hint] => &amp;#36;95
2112 [rangetime] => 10:00 AM - 12:00 PM
2113 [name] => test
2114 [email] => test@wpbookingcalendar.com
2115 ...
2116 )
2117
2118 * @param array $booking_system_arr array of system fields from DB
2119 Array ( [booking_id] => 188
2120 [trash] => 0
2121 ...
2122 [cost] => 95.00
2123 [pay_status] => 165036591118.88
2124 [pay_request] => 0
2125 [id] => 188
2126 [approved] => 0
2127 )
2128
2129 * @param array $system_keys_arr system fields keys that need to be added, like this:
2130 Array ( booking_id, trash, sync_gid, is_new, status
2131 , sort_date, modification_date, hash, booking_type
2132 , remark, cost, pay_status, pay_request, id, approved )
2133
2134 * @return array array of form fields with system fields
2135 */
2136 function wpbc_add_system_booking_data_fields( $booking_data_arr, $booking_system_arr, $system_keys_arr ){
2137
2138 foreach ( $system_keys_arr as $key ) {
2139
2140 if (
2141 ( ! isset( $booking_system_arr[ $key ] ) )
2142 || ( is_null( $booking_system_arr[ $key ] ) )
2143 ) {
2144 $booking_system_arr[ $key ] = ''; //Some fields, like remark or booking_options can be null, so we define them as ''
2145 }
2146
2147 if ( isset( $booking_system_arr[ $key ] ) ) {
2148
2149 if ( ! isset( $booking_data_arr[ $key ] ) ) {
2150 $booking_data_arr[ $key ] = maybe_unserialize( $booking_system_arr[ $key ] );
2151 } else {
2152 $booking_data_arr[ $key . '_system' ] = maybe_unserialize( $booking_system_arr[ $key ] );
2153 }
2154 }
2155
2156 }
2157 return $booking_data_arr;
2158 }
2159
2160
2161 /**
2162 * Parse booking form fields format - for example: time fields in specific format
2163 * @param $data_arr
2164 *
2165 * @return array
2166 */
2167 function wpbc_parse_booking_data_fields_formats( $data_arr ){
2168
2169 foreach ( $data_arr as $key => $value ) {
2170
2171 if ( 'rangetime' == $key ) {
2172 $data_arr[$key] = wpbc_time_slot_in_format( $value );
2173 $data_arr[ $key . '_in_24_hour' ] = $value; // FixIn: 10.0.0.52.
2174 }
2175
2176 if ( in_array( $key, array( 'starttime', 'endtime' ) ) ) {
2177 $data_arr[$key] = wpbc_time_in_format( $value );
2178 $data_arr[ $key . '_in_24_hour' ] = $value; // FixIn: 10.0.0.52.
2179 }
2180
2181 if ( in_array( $key, array( 'modification_date', 'creation_date' ) ) ) {
2182
2183 //$data_arr[$key] = wpbc_get_dates_comma_string_localized( $value );
2184
2185
2186 // 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.
2187 $is_add_wp_timezone = true;
2188 $its_for_default_datetime_format = '';
2189 $data_arr[ $key ] = wpbc_datetime_localized( $value, $its_for_default_datetime_format, $is_add_wp_timezone );
2190 $data_arr[ $key . '_in_24_hour' ] = $value; // FixIn: 10.0.0.52.
2191 }
2192
2193 if ( ( 'hash' === $key ) && ( empty( $value ) ) ) { //FixIn: 9.2.3.4 // FixIn: 9.4.3.10.
2194 // Update booking Hash if it was empty
2195 wpbc_hash__update_booking_hash( $data_arr['id'], $data_arr['booking_type'] );
2196 // Get new booking hash
2197 $hash__arr = wpbc_hash__get_booking_hash__resource_id( $data_arr['id'] );
2198 if ( ! empty( $hash__arr ) ) {
2199 $data_arr[ $key ] = $hash__arr[0];
2200 }
2201 }
2202 }
2203 return $data_arr;
2204 }
2205
2206
2207 /**
2208 * Get pure "Content of booking fields data" with shortcodes inside.
2209 * it can depend on specific booking resource in Business Medium version or User in MultiUser version
2210 *
2211 * @param int $resource_id
2212 * @param sting $custom_booking_form_name - use this custom booking form, if possible
2213 *
2214 * @return string
2215 */
2216 function wpbc_get_content_booking_form_show( $resource_id , $custom_booking_form_name = '' ){ // FixIn: 9.4.3.12.
2217
2218 if ( $resource_id == -1 ) {
2219 if ( function_exists('get__default_type') )
2220 $resource_id = get__default_type();
2221 else
2222 $resource_id = 1;
2223 }
2224
2225 if ( ! class_exists('wpdev_bk_personal') ) {
2226
2227 $booking_form_show = wpbc_simple_form__get_form_show__as_shortcodes();
2228 $booking_form_show = wpbc_bf__replace_custom_html_shortcodes( $booking_form_show );
2229
2230 } else {
2231
2232 $booking_form_show = get_bk_option( 'booking_form_show' );
2233 $booking_form_show = wpbc_bf__replace_custom_html_shortcodes( $booking_form_show );
2234
2235 if ( class_exists('wpdev_bk_biz_m') ) {
2236
2237 if ( ! empty( $custom_booking_form_name ) ) { // FixIn: 9.4.3.12.
2238
2239 $booking_form_show = apply_bk_filter( 'wpdev_get_booking_form_content', $booking_form_show, $custom_booking_form_name );
2240 $my_booking_form_name = $custom_booking_form_name;
2241 } else {
2242 // BM :: Get default Custom Form of Resource
2243 $my_booking_form_name = apply_bk_filter( 'wpbc_get_default_custom_form', 'standard', $resource_id );
2244 if ( ( $my_booking_form_name != 'standard' ) && ( ! empty( $my_booking_form_name ) ) ) {
2245 $booking_form_show = apply_bk_filter( 'wpdev_get_booking_form_content', $booking_form_show, $my_booking_form_name );
2246 }
2247 }
2248 //MU :: if resource of "Regular User" - then GET STANDARD user form ( if ( get_bk_option( 'booking_is_custom_forms_for_regular_users' ) !== 'On' ) )
2249 $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.
2250
2251 }
2252 }
2253
2254 // Language
2255 $booking_form_show = wpbc_lang( $booking_form_show );
2256
2257 $search = array( "'(<br[ ]?[/]?>)+'si", "'(<[/]?p[ ]?>)+'si" );
2258 $replace = array( "&nbsp;&nbsp;", " &nbsp; ", " &nbsp; " );
2259 $booking_form_show = preg_replace( $search, $replace, $booking_form_show );
2260
2261 return $booking_form_show;
2262 }
2263
2264
2265 /**
2266 * Get parsed "Content of booking fields data" - Shortcodes replaced by Values
2267 *
2268 * @param array $booking_data_arr
2269 * @param string $booking_form_show
2270 *
2271 * @return string
2272 */
2273 function wpbc_get_parsed_content_booking_form_show( $booking_data_arr, $booking_form_show ){
2274
2275 foreach ( $booking_data_arr as $key_param => $value_param ) {
2276 if ( ( gettype ( $value_param ) != 'array' )
2277 && ( gettype ( $value_param ) != 'object' )
2278 ) {
2279 $booking_form_show = str_replace( '['. $key_param .']', $value_param ,$booking_form_show);
2280 }
2281 }
2282 // Remove all shortcodes, which have not replaced early.
2283 $booking_form_show = preg_replace ('/[\s]{0,}\[[a-zA-Z0-9.,-_]{0,}\][\s]{0,}/', '', $booking_form_show);
2284
2285 $booking_form_show = str_replace( "&amp;", '&', $booking_form_show );
2286
2287 return $booking_form_show;
2288 }
2289
2290 // </editor-fold>
2291
2292
2293 // <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 " >
2294
2295 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2296 // Escaping
2297 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2298
2299 /**
2300 * Escaping for inline JavaScript.
2301 * Based on WordPress esc_js()
2302 * plus removing \n in the code
2303 * and back converting escaped single quotes from \' to '
2304 *
2305 * This function has to be used in the code marked with double quote symbols, not single.
2306 * Example: onclick="javascript:<?php
2307 // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
2308 echo wpbc_esc_js( $item_params['action'] ); ?>"
2309 *
2310 * @param $text
2311 *
2312 * @return string
2313 */
2314 function wpbc_esc_js( $text ) {
2315
2316 $text = str_replace( "\n", '', $text ); // removing \n in the code
2317
2318 //$safe_text = esc_js( $text ); // js
2319
2320 // This code get from esc_js() and modified for correct working with (' symbols) in translations
2321 $safe_text = wp_check_invalid_utf8( $text );
2322 $safe_text = _wp_specialchars( $safe_text, ENT_COMPAT );
2323 $safe_text = preg_replace( '/&#(x)?0*(?(1)27|39);?/i', "\'", stripslashes( $safe_text ) );
2324 $safe_text = str_replace( "\r", '', $safe_text );
2325 $safe_text = str_replace( "\n", '\\n', addslashes( $safe_text ) );
2326
2327 $safe_text = str_replace( "\'", "'", $safe_text ); // back converting escaped single quotes from \' to '
2328 $safe_text = str_replace( "\\\'", "\'", $safe_text ); // back converting escaped single quotes from \' to '
2329
2330 return $safe_text;
2331 }
2332
2333
2334 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2335 // DB
2336 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2337
2338 /**
2339 * Check $value for injections. Basically can be used in Requests params checking.
2340 *
2341 * @param type $value
2342 *
2343 * @return type
2344 */
2345 function wpbc_esc_clean_parameter( $value ) {
2346
2347 $value = preg_replace( '/<[^>]*>/', '', $value ); // clean any tags
2348 $value = str_replace( '<', ' ', $value );
2349 $value = str_replace( '>', ' ', $value );
2350 $value = wp_strip_all_tags( $value ); // Strip HTML and PHP tags from a string
2351
2352 // Clean SQL injection
2353 $value = esc_sql( $value );
2354 $value = esc_textarea( $value ); // FixIn: 7.1.1.2.
2355
2356 return $value;
2357 }
2358
2359
2360 function wpbc_esc_sql_like( $value_trimmed ) {
2361
2362 // check here https://code.tutsplus.com/articles/data-sanitization-and-validation-with-wordpress--wp-25536
2363
2364 global $wpdb;
2365 if ( method_exists( $wpdb ,'esc_like' ) )
2366 return $wpdb->esc_like( $value_trimmed ); // Its require minimum WP 4.0.0
2367 else
2368 return addcslashes( $value_trimmed, '_%\\' ); // Direct implementation from $wpdb->esc_like(
2369 }
2370
2371
2372 /**
2373 * Clean user string for using in SQL LIKE statement - append to LIKE sql
2374 *
2375 * @param string $value - to clean
2376 *
2377 * @return string - escaped
2378 * Exmaple:
2379 * $search_escaped_like_title = wpbc_esc_clean_like_string_for_append_in_sql_for_db( $input_var );
2380 *
2381 * $where_sql = " WHERE title LIKE ". $search_escaped_like_title ." ";
2382 */
2383 function wpbc_esc_clean_like_string_for_append_in_sql_for_db( $value ) {
2384
2385 // check here https://code.tutsplus.com/articles/data-sanitization-and-validation-with-wordpress--wp-25536
2386
2387 global $wpdb;
2388
2389 $value_trimmed = trim( stripslashes( $value ) );
2390
2391 $wild = '%';
2392 $like = $wild . wpbc_esc_sql_like( $value_trimmed ) . $wild;
2393
2394 /* phpcs:ignore WordPress.DB.PreparedSQLPlaceholders.QuotedSimplePlaceholder */
2395 $sql = $wpdb->prepare( "'%s'", $like );
2396
2397 return $sql;
2398
2399
2400 /* Help:
2401 * First half of escaping for LIKE special characters % and _ before preparing for MySQL.
2402 * Use this only before wpdb::prepare() or esc_sql(). Reversing the order is very bad for security.
2403 *
2404 * Example Prepared Statement:
2405 *
2406 * $wild = '%';
2407 * $find = 'only 43% of planets';
2408 * $like = $wild . wpbc_esc_sql_like( $find ) . $wild;
2409 * $sql = $wpdb->prepare( "SELECT * FROM $wpdb->posts WHERE post_content LIKE '%s'", $like );
2410 *
2411 * Example Escape Chain:
2412 *
2413 * $sql = esc_sql( wpbc_esc_sql_like( $input ) );
2414 */
2415
2416 }
2417
2418
2419 /**
2420 * Clean string for using in SQL LIKE requests inside single quotes: WHERE title LIKE '%". $escaped_search_title ."%'
2421 * Replaced _ to \_ % to \% \ to \\
2422 *
2423 * @param string $value - to clean
2424 *
2425 * @return string - escaped
2426 * Exmaple:
2427 * $search_escaped_like_title = wpbc_esc_clean_like_string_for_db( $input_var );
2428 *
2429 * $where_sql = " WHERE title LIKE '%". $search_escaped_like_title ."%' ";
2430 *
2431 * Important! Use SINGLE quotes after in SQL query: LIKE '%".$data."%'
2432 */
2433 function wpbc_esc_clean_like_string_for_db( $value ){
2434
2435 // check here https://code.tutsplus.com/articles/data-sanitization-and-validation-with-wordpress--wp-25536
2436
2437 global $wpdb;
2438
2439 $value_trimmed = trim( stripslashes( $value ) );
2440
2441 $value_trimmed = wpbc_esc_sql_like( $value_trimmed );
2442
2443 /* phpcs:ignore WordPress.DB.PreparedSQLPlaceholders.QuotedSimplePlaceholder */
2444 $value = trim( $wpdb->prepare( "'%s'", $value_trimmed ) , "'" );
2445
2446 return $value;
2447
2448 /* Help:
2449 * First half of escaping for LIKE special characters % and _ before preparing for MySQL.
2450 * Use this only before wpdb::prepare() or esc_sql(). Reversing the order is very bad for security.
2451 *
2452 * Example Prepared Statement:
2453 *
2454 * $wild = '%';
2455 * $find = 'only 43% of planets';
2456 * $like = $wild . wpbc_esc_sql_like( $find ) . $wild;
2457 * $sql = $wpdb->prepare( "SELECT * FROM $wpdb->posts WHERE post_content LIKE '%s'", $like );
2458 *
2459 * Example Escape Chain:
2460 *
2461 * $sql = esc_sql( wpbc_esc_sql_like( $input ) );
2462 */
2463 }
2464
2465
2466 // </editor-fold>
2467
2468
2469 // <editor-fold defaultstate="collapsed" desc=" D B " >
2470
2471 /***
2472 * Get list of DB of this plugin
2473 * @return array
2474 */
2475 function wpbc_get_db_names(){
2476
2477 global $wpdb;
2478
2479 $db_names = array(
2480 'bookings' => $wpdb->prefix . 'booking',
2481 'dates' => $wpdb->prefix . 'bookingdates',
2482 'resources' => $wpdb->prefix . 'bookingtypes',
2483 'resources_meta' => $wpdb->prefix . 'booking_types_meta',
2484 'seasons' => $wpdb->prefix . 'booking_seasons',
2485 'coupons' => $wpdb->prefix . 'booking_coupons'
2486 );
2487
2488 return $db_names;
2489 }
2490
2491 // </editor-fold>
2492
2493
2494 // <editor-fold defaultstate="collapsed" desc=" E r r o r s H a n d l i n g " >
2495
2496 /**
2497 * PHP Fatal Error! Display expanded error info at Booking Listing page
2498 *
2499 * @param $message
2500 * @param $error
2501 *
2502 * @return mixed|string
2503 */
2504 function wpbc_php_error_message( $message, $error ) {
2505
2506 // 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
2507 // phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.NonceVerification.Missing
2508 if ( ! ( ! isset( $_POST['search_params'] ) || empty( $_POST['search_params'] ) ) ) {
2509 // Security ----------------------------------------------------------------------------------------------- // in Ajax Post: 'nonce': wpbc_ajx_booking_listing.get_secure_param( 'nonce' ),
2510 $action_name = 'wpbc_ajx_booking_listing_ajx' . '_wpbcnonce';
2511 $nonce_post_key = 'nonce';
2512 // $result_check = check_ajax_referer( $action_name, $nonce_post_key );
2513 // phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.NonceVerification.Missing
2514 if ( isset( $_REQUEST[ $nonce_post_key ] ) ) {
2515 // phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.NonceVerification.Missing, WordPress.Security.ValidatedSanitizedInput.MissingUnslash, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
2516 $nonce_request = $_REQUEST[ $nonce_post_key ];
2517
2518 $result_verify_nonce = wp_verify_nonce( $nonce_request, $action_name );
2519
2520 if ( false !== $result_verify_nonce ) {
2521 if ( ( ! empty( $error ) ) && ( ! empty( $error['message'] ) ) ) {
2522 $message .= '<br>' . $error['message'];
2523 }
2524 }
2525 }
2526 }
2527
2528 return $message;
2529 }
2530 add_filter( 'wp_php_error_message', 'wpbc_php_error_message', 2 , 10 );
2531
2532
2533 /**
2534 * Nonce Error! Error Handing for not passed nonce, in booking Listing page.
2535 * Probably nonce was expired (more than 24 hours)
2536 *
2537 * @param $action
2538 * @param $result - 1 Good ( 0-12 hours ago ) , 2 Good ( 12-24 hours ago ) , false - Error ( > 24 hours - nonce is invalid )
2539 */
2540 function wpbc_check_ajax_referer__for_booking_listing( $action, $result ){
2541 if (
2542 ( false === $result )
2543 && ( 'wpbc_ajx_booking_listing_ajx' . '_wpbcnonce' === $action )
2544 && ( wp_doing_ajax() )
2545 ) {
2546 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>.' );
2547 }
2548 }
2549 add_action( 'check_ajax_referer', 'wpbc_check_ajax_referer__for_booking_listing', 2, 10 );
2550 // </editor-fold>