PluginProbe
Booking Calendar / 11.2.1
Booking Calendar v11.2.1
11.9 11.8.4 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 All 205 releases
booking / includes / page-bookings / bookings__actions.php

bookings__actions.php in Booking Calendar 11.2.1, at includes/page-bookings/bookings__actions.php

2,397 lines 108.4 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 AJX_Bookings
4 * @category AJX_Bookings Actions
5 * @author wpdevelop
6 *
7 * @web-site http://oplugins.com/
8 * @email [email protected]
9 *
10 * @modified 2022-06-10
11 */
12
13 if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
14
15 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
16 // Main Ajax handler
17 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
18
19 /**
20 * Ajax Actions - Get Listing Data and Response to JS script
21 */
22 function wpbc_ajax_WPBC_AJX_BOOKING_ACTIONS() {
23
24 // phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.NonceVerification.Missing
25 if ( ! isset( $_POST['action_params'] ) || empty( $_POST['action_params'] ) ) {
26 exit;
27 }
28
29 $ajax_errors = new WPBC_AJAX_ERROR_CATCHING();
30
31 // Security ----------------------------------------------------------------------------------------------- // in Ajax Post: 'nonce': wpbc_ajx_booking_listing.get_secure_param( 'nonce' ),
32 $action_name = 'wpbc_ajx_booking_listing_ajx' . '_wpbcnonce';
33 $nonce_post_key = 'nonce';
34 $result_check = check_ajax_referer( $action_name, $nonce_post_key );
35
36 $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
37
38 // Get clean Parameters for SQL ---------------------------------------------------------------------------
39 $request_rules_structure = array(
40 'booking_action' => array( 'validate' => array(
41 'set_booking_locale',
42 'set_booking_pending' ,
43 'set_booking_approved',
44 'move_booking_to_trash',
45 'restore_booking_from_trash',
46 'delete_booking_completely',
47 'set_booking_as_read',
48 'set_booking_as_unread',
49 'empty_trash',
50 'set_booking_note',
51 'change_booking_resource',
52 'duplicate_booking_to_other_resource',
53 'set_payment_status',
54 'set_booking_cost',
55 'send_payment_request',
56 'import_google_calendar',
57 'export_csv',
58 'feedback_01'
59
60 ), 'default' => '' ),
61 'booking_id' => array( 'validate' => 'digit_or_csd', 'default' => 0 ),
62 'selected_resource_id' => array( 'validate' => 'd', 'default' => 0 ),
63 'booking_meta_locale' => array( 'validate' => 's', 'default' => '' ),
64 'reason_of_action' => array( 'validate' => 's', 'default' => '' ),
65 'remark' => array( 'validate' => 's', 'default' => '' ),
66 'ui_clicked_element_id' => array( 'validate' => 's', 'default' => '' ),
67 'selected_payment_status' => array( 'validate' => 's', 'default' => '' ),
68 'booking_cost' => array( 'validate' => 's', 'default' => '' ),
69
70 'export_type' => array( 'validate' => array( 'csv_all', 'csv_page' ), 'default' => 'csv_page' ),
71 'csv_export_separator' => array( 'validate' => array( 'semicolon', 'comma' ), 'default' => ';' ),
72 'csv_export_skip_fields' => array( 'validate' => 's', 'default' => '' ),
73
74 'booking_gcal_events_from' => array( 'validate' => 's', 'default' => '' ),
75 'booking_gcal_events_from_offset' => array( 'validate' => 's', 'default' => '' ),
76 'booking_gcal_events_from_offset_type' => array( 'validate' => 's', 'default' => '' ),
77 'booking_gcal_events_until' => array( 'validate' => 's', 'default' => '' ),
78 'booking_gcal_events_until_offset' => array( 'validate' => 's', 'default' => '' ),
79 'booking_gcal_events_until_offset_type' => array( 'validate' => 's', 'default' => '' ),
80 'booking_gcal_events_max' => array( 'validate' => 'd', 'default' => 25 ),
81 'booking_gcal_resource' => array( 'validate' => 's', 'default' => '' ),
82
83 'feedback__note' => array( 'validate' => 's', 'default' => '' ),
84 'feedback_stars' => array( 'validate' => 'd', 'default' => 0 )
85 );
86
87 $user_request = new WPBC_AJX__REQUEST( array(
88 'db_option_name' => 'booking_listing_request_params',
89 'user_id' => wpbc_get_current_user_id(),
90 'request_rules_structure' => $request_rules_structure
91 )
92 );
93 $request_prefix = 'action_params';
94 $request_params = $user_request->get_sanitized__in_request__value_or_default( $request_prefix ); // NOT Direct: $_REQUEST['action_params']['resource_id']
95
96
97
98
99
100 $action_result = array();
101
102 switch ( $request_params['booking_action'] ) {
103
104 case 'set_booking_locale':
105 $action_result = wpbc_booking_do_action__set_booking_locale( $request_params['booking_id']
106 , array(
107 'user_id' => $user_id,
108 'booking_locale' => $request_params['booking_meta_locale']
109 )
110 );
111 break;
112
113 case 'set_booking_pending': // Pending
114 $action_result = wpbc_booking_do_action__set_booking_approved_or_pending( $request_params['booking_id']
115 , array(
116 'user_id' => $user_id,
117 'reason_of_action' => $request_params['reason_of_action'],
118 'is_approve' => '0'
119 )
120 );
121 break;
122
123 case 'set_booking_approved': // Approve
124 $action_result = wpbc_booking_do_action__set_booking_approved_or_pending( $request_params['booking_id']
125 , array(
126 'user_id' => $user_id,
127 'reason_of_action' => $request_params['reason_of_action'],
128 'is_approve' => '1'
129 )
130 );
131 break;
132
133 case 'move_booking_to_trash': // Approve
134 $action_result = wpbc_booking_do_action__trash_booking_or_restore( $request_params['booking_id']
135 , array(
136 'user_id' => $user_id,
137 'reason_of_action' => $request_params['reason_of_action'],
138 'is_trash' => '1'
139 )
140 );
141 break;
142
143 case 'restore_booking_from_trash':
144 $action_result = wpbc_booking_do_action__trash_booking_or_restore( $request_params['booking_id']
145 , array(
146 'user_id' => $user_id,
147 'reason_of_action' => $request_params['reason_of_action'],
148 'is_trash' => '0'
149 )
150 );
151 break;
152
153 case 'delete_booking_completely':
154 $action_result = wpbc_booking_do_action__delete_booking_completely( $request_params['booking_id']
155 , array(
156 'user_id' => $user_id,
157 'reason_of_action' => $request_params['reason_of_action'],
158 )
159 );
160 break;
161
162 case 'set_booking_as_read':
163 $action_result = wpbc_booking_do_action__set_booking_as_read_unread( $request_params['booking_id']
164 , array(
165 'user_id' => $user_id,
166 'is_new' => '0'
167 )
168 );
169 break;
170
171 case 'set_booking_as_unread':
172 $action_result = wpbc_booking_do_action__set_booking_as_read_unread( $request_params['booking_id']
173 , array(
174 'user_id' => $user_id,
175 'is_new' => '1'
176 )
177 );
178 break;
179
180 case 'empty_trash':
181 $action_result = wpbc_booking_do_action__empty_trash( array(
182 'user_id' => $user_id
183 ) );
184 break;
185
186 case 'set_booking_note':
187 $action_result = wpbc_booking_do_action__set_booking_note( $request_params['booking_id']
188 , array(
189 'user_id' => $user_id,
190 'remark' => $request_params['remark'],
191 )
192 );
193 break;
194
195 case 'change_booking_resource': // Pending
196 $action_result = wpbc_booking_do_action__change_booking_resource( $request_params['booking_id']
197 , $request_params['selected_resource_id']
198 , array(
199 'user_id' => $user_id
200 )
201 );
202 break;
203 case 'duplicate_booking_to_other_resource':
204 $action_result = wpbc_booking_do_action__duplicate_booking_to_other_resource( $request_params['booking_id']
205 , $request_params['selected_resource_id']
206 , array(
207 'user_id' => $user_id
208 )
209 );
210 break;
211 case 'set_payment_status':
212 $action_result = wpbc_booking_do_action__set_payment_status( $request_params['booking_id']
213 , $request_params['selected_payment_status']
214 , array(
215 'user_id' => $user_id
216 )
217 );
218 break;
219 case 'set_booking_cost':
220 $action_result = wpbc_booking_do_action__set_booking_cost( $request_params['booking_id']
221 , $request_params['booking_cost']
222 , array(
223 'user_id' => $user_id
224 )
225 );
226 break;
227 case 'send_payment_request':
228 $action_result = wpbc_booking_do_action__send_payment_request( $request_params['booking_id']
229 , $request_params['reason_of_action']
230 , array(
231 'user_id' => $user_id
232 )
233 );
234 break;
235
236 case 'import_google_calendar':
237 $action_result = wpbc_booking_do_action__import_google_calendar( $request_params
238 , array(
239 'user_id' => $user_id
240 )
241 );
242 break;
243
244 case 'export_csv':
245
246 $action_result = wpbc_booking_do_action__export_csv( $request_params
247 , array(
248 'user_id' => $user_id
249 )
250 );
251 break;
252
253 case 'feedback_01':
254
255 $action_result = wpbc_booking_do_action__feedback_01( $request_params
256 , array(
257 'user_id' => $user_id
258 )
259 );
260 break;
261
262 default:
263 }
264
265
266 $defaults = array(
267 'new_listing_params' => false // required for Import Google Calendar bookings
268 , 'after_action_result' => false
269 /* translators: 1: ... */
270 , 'after_action_message' => sprintf( __( 'No actions %s has been processed.', 'booking')
271 , ' <strong>' . $request_params['booking_action'] . '</strong> ' )
272 );
273 $action_result = wp_parse_args( $action_result, $defaults );
274
275 // Check if there were some errors --------------------------------------------------------------------------------
276 $error_messages = $ajax_errors->get_error_messages();
277 if ( ! empty( $error_messages ) ) {
278 $action_result['after_action_message'] .= $error_messages;
279 }
280
281 // Hook for other integrations
282 do_action( 'wpbc_' . $request_params['booking_action'], $request_params, $action_result ); // FixIn: 9.5.3.3.
283
284 //------------------------------------------------------------------------------------------------------------------
285 // Send JSON. Its will make "wp_json_encode" - so pass only array, and This function call wp_die( '', '', array( 'response' => null, ) ) Pass JS OBJ: response_data in "jQuery.post( " function on success.
286 wp_send_json( array(
287 // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotValidated, WordPress.Security.ValidatedSanitizedInput.MissingUnslash, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
288 'ajx_action_params' => $_REQUEST['action_params'], // Do not clean input parameters.
289 'ajx_cleaned_params' => $request_params, // Cleaned input parameters.
290 'ajx_after_action_message' => $action_result['after_action_message'], // Message to show.
291 'ajx_after_action_result' => (int) $action_result['after_action_result'], // Result key 0 | 1.
292 'ajx_after_action_result_all_params_arr' => $action_result, // All result parameters.
293 ) );
294 }
295
296
297 // <editor-fold defaultstate="collapsed" desc=" == Ajax Actions for bookings == " >
298
299 /**
300 * Action: set booking as Locale
301 *
302 * @param int $booking_id ID of booking 10
303 * @param $params
304 *
305 * @return array
306 */
307 function wpbc_booking_do_action__set_booking_locale( $booking_id, $params ){
308
309 $booking_locale = $params['booking_locale'];
310
311 // LOG ---------------------------------------------------------------------------------------------------------
312 $curr_user = get_user_by( 'id', (int) $params['user_id'] );
313 wpbc_db__add_log_info( $booking_id,
314 /* translators: 1: ... */
315 sprintf( __( 'Booking locale changed to %s by:', 'booking' ), $booking_locale )
316 . ' ' . $curr_user->first_name . ' ' . $curr_user->last_name . ' (' . $curr_user->user_email . ')'
317 );
318
319 // Action ---------------------------------------------------------------------------------------------------------
320 $option_arr = array( 'booking_meta_locale' => $booking_locale );
321
322 $result = wpbc_save_booking_meta_option( $booking_id, $option_arr );
323
324 if ( $result ) {
325 $after_action_result = true;
326 $after_action_message = ( ( false === strpos( $booking_id, ',' ) )
327 /* translators: 1: ... */
328 ? sprintf( __( 'Booking has been changed locale to %s', 'booking' ), "<strong>{$booking_locale}</strong>" )
329 /* translators: 1: ... */
330 : sprintf( __( 'Bookings have been changed locale to %s', 'booking' ), "<strong>{$booking_locale}</strong>" )
331 )
332 . ' <span style="font-size:0.9em;">( ID = <strong>' . $booking_id . '</strong> )</span>';
333 } else {
334 $after_action_result = false;
335 $after_action_message = ( ( false === strpos( $booking_id, ',' ) )
336 /* translators: 1: ... */
337 ? sprintf( __( 'Booking has NOT been changed locale to %s', 'booking' ), "<strong>{$booking_locale}</strong>" )
338 /* translators: 1: ... */
339 : sprintf( __( 'Bookings have NOT been changed locale to %s', 'booking' ), "<strong>{$booking_locale}</strong>" )
340 )
341 . ' <span style="font-size:0.9em;">( ID = <strong>' . $booking_id . '</strong> )</span>';
342 }
343
344 return array(
345 'after_action_result' => $after_action_result,
346 'after_action_message' => $after_action_message
347 );
348 }
349
350 /**
351 * Action: Get Google Calendar Link
352 *
353 * @param $booking_data array(
354 'form_data' => array( ... )
355 'form_show' => ....
356 'dates_short' => array( ... )
357 )
358 *
359 * @return string URL of encoded link for adding to Google Calendar
360 */
361 function wpbc_booking_do_action__get_google_calendar_link( $booking_data ){
362
363 $params = array();
364 $params['timezone'] = get_bk_option('booking_gcal_timezone');
365
366 $booking_gcal_events_form_fields = maybe_unserialize( get_bk_option( 'booking_gcal_events_form_fields') ); // array( [title]=>text^name, [description]=>textarea^details, [where]=>text^ )
367
368 // Fields ----------------------------------------------------------------------------------------------------------
369 $fields = array( 'title' => '', 'description' => '', 'where' => '' );
370
371 foreach ( $fields as $key_name => $field_value ) {
372
373 if ( ! empty( $booking_gcal_events_form_fields[ $key_name ] ) ) {
374
375 $field_name = explode( '^', $booking_gcal_events_form_fields[ $key_name ] );
376
377 $field_name = $field_name[ ( count( $field_name ) - 1 ) ]; // FixIn: 8.7.7.6.
378
379 if ( 'description' === $key_name ) { // FixIn: 8.1.3.2.
380
381 if ( isset( $booking_data['form_show'] ) ) { // FixIn: 8.7.3.14.
382 // FixIn: 8.7.11.4.
383 $fields[ $key_name ] = $booking_data['form_show'];
384 $fields[ $key_name ] = htmlspecialchars_decode($fields[ $key_name ], ENT_QUOTES );
385 $fields[ $key_name ] = urlencode($fields[ $key_name ]);
386 $fields[ $key_name ] = htmlentities($fields[ $key_name ] );
387 $fields[ $key_name ] = htmlspecialchars_decode ( $fields[ $key_name ], ENT_NOQUOTES );
388 }
389
390 } else if ( ( ! empty( $field_name ) )
391 && ( ! empty( $booking_data['form_data'] ) )
392 && ( ! empty( $booking_data['form_data'][ $field_name ] ) )
393 ) {
394 // FixIn: 8.7.11.4.
395 $fields[ $key_name ] = $booking_data['form_data'][ $field_name ];
396 $fields[ $key_name ] = htmlspecialchars_decode($fields[ $key_name ], ENT_QUOTES );
397 /**
398 * // Convert here from usual symbols to URL symbols https://www.url-encode-decode.com/
399 $fields[ $key_name ] = str_replace( array( '%','#', '+', '&' )
400 , array( '%25','%23', '%2B', '%26')
401 , $fields[ $key_name ]
402 );
403 */
404 $fields[ $key_name ] = urlencode($fields[ $key_name ]);
405 $fields[ $key_name ] = htmlentities($fields[ $key_name ] );
406 $fields[ $key_name ] = htmlspecialchars_decode ( $fields[ $key_name ], ENT_NOQUOTES );
407 }
408 }
409 }
410
411 // Dates -----------------------------------------------------------------------------------------------------------
412 $check_in_timestamp = $check_out_timestamp = '';
413 if ( ! empty( $booking_data[ 'dates_short' ] ) ) {
414
415 /**
416 * All day events, you can use 20161208/20161209 - note that the old google documentation gets it wrong.
417 * You must use the following date as the end date for a one day all day event,
418 * or +1 day to whatever you want the end date to be.
419 */
420
421 $check_in_timestamp = strtotime( $booking_data[ 'dates_short' ][ 0 ], current_time( 'timestamp' ) );
422 $check_out_timestamp = strtotime( $booking_data[ 'dates_short' ][ ( count( $booking_data[ 'dates_short' ] ) - 1 ) ], current_time( 'timestamp' ) );
423
424 if ( trim( substr( $booking_data[ 'dates_short' ][ 0 ], 11 ) ) == '00:00:00' ) {
425 if ( trim( substr( $booking_data[ 'dates_short' ][ ( count( $booking_data[ 'dates_short' ] ) - 1 ) ], 11 ) ) == '00:00:00' ) {
426 $check_in_timestamp = gmdate( "Ymd", $check_in_timestamp ); // All day
427 } else {
428 $check_in_timestamp = gmdate( "Ymd\T000000", $check_in_timestamp ); // All day starting on 00:00:00 // FixIn: 10.0.0.28.
429 }
430 } else {
431 $check_in_timestamp = gmdate( "Ymd\THis", $check_in_timestamp ); //$check_in_timestamp = gmdate( "Ymd\THis\Z", $check_in_timestamp );
432 }
433
434 if ( trim( substr( $booking_data[ 'dates_short' ][ ( count( $booking_data[ 'dates_short' ] ) - 1 ) ], 11 ) ) == '00:00:00' ) {
435 $check_out_timestamp = strtotime( '+1 day', $check_out_timestamp );
436 $check_out_timestamp = gmdate( "Ymd", $check_out_timestamp ); // All day
437 } else {
438 $check_out_timestamp = gmdate( "Ymd\THis", $check_out_timestamp ); //$check_out_timestamp = gmdate( "Ymd\THis\Z", $check_out_timestamp );
439 }
440 }
441
442 // Link -----------------------------------------------------------------------------------------------------------
443 /**
444 * Convert an ISO date/time to a UNIX timestamp
445 function iso_to_ts( $iso ) {
446 sscanf( $iso, "%u-%u-%uT%u:%u:%uZ", $year, $month, $day, $hour, $minute, $second );
447 return mktime( $hour, $minute, $second, $month, $day, $year );
448 20140127T224000Z
449 gmdate("Ymd\THis\Z", time());
450 */
451
452 /**
453 * action: action=TEMPLATE
454 A default required parameter.
455
456 src:
457 Example: src=default%40gmail.com
458 Format: src=text
459 This is not covered by Google help but is an optional parameter in order to add an event to a shared calendar rather than a user's default.
460
461 text:
462 Example: text=Garden%20Waste%20Collection
463 Format: text=text
464 This is a required parameter giving the event title.
465
466 dates:
467 Example: dates=20090621T063000Z/20090621T080000Z (i.e. an event on 21 June 2009 from 7.30am to 9.0am British Summer Time (=GMT+1)).
468 Format: dates=YYYYMMDDToHHMMSSZ/YYYYMMDDToHHMMSSZ
469 This required parameter gives the start and end dates and times (in Greenwich Mean Time) for the event.
470
471 location:
472 Example: location=Home
473 Format: location=text
474 The obvious location field.
475
476 trp:
477 Example: trp=false
478 Format: trp=true/false
479 Show event as busy (true) or available (false)
480
481 sprop:
482 Example: sprop=http%3A%2F%2Fwww.me.org
483 Example: sprop=name:Home%20Page
484 Format: sprop=website and/or sprop=name:website_name
485 */
486
487 //$link_add2gcal = 'http://www.google.com/calendar/event?action=TEMPLATE';
488 //$link_add2gcal .= '&text=' . $fields['title'];
489 $link_add2gcal = 'https://calendar.google.com/calendar/r/eventedit?'; // FixIn: 8.7.3.10.
490 $link_add2gcal .= 'text=' . $fields['title']; // FixIn: 8.7.11.4.
491 $link_add2gcal .= '&dates=' . $check_in_timestamp . '/' . $check_out_timestamp; //$link_add2gcal .= '&dates=[start-custom format='Ymd\\THi00\\Z']/[end-custom format='Ymd\\THi00\\Z']';
492 $link_add2gcal .= '&details=' . ( ( 'On' !== get_bk_option( 'booking_g_cal_export_no_data' ) ) ? $fields['description'] : '' ); //FixIn: 10.3.0.1 // FixIn: 8.7.11.4.
493 $link_add2gcal .= '&location=' . ( ( 'On' !== get_bk_option( 'booking_g_cal_export_no_data' ) ) ? $fields['where'] : '' ); // FixIn: 8.7.11.4.
494 $link_add2gcal .= '&trp=false';
495 if ( ! empty( $params['timezone'] ) ) {
496 $link_add2gcal .= '&ctz=' . str_replace( '%', '%25', $params['timezone'] ); //FixIn: 8.7.3.10 //TimeZone
497 }
498 //$link_add2gcal .= '&sprop=';
499 //$link_add2gcal .= '&sprop=name:';
500
501 return $link_add2gcal;
502 }
503
504 /**
505 * Action: move booking to Trash | Restore
506 *
507 * @param $booking_id_arr array or int of booking ID
508 * @param $params array array of parameters: array( 'user_id' => 1, 'reason_of_action' => 'Because...', 'is_trash' => '1' )
509 *
510 * @return array
511 *
512 * Example:
513 */
514 function wpbc_booking_do_action__trash_booking_or_restore( $booking_id_arr, $params ){
515
516 make_bk_action('check_multiuser_params_for_client_side_by_user_id', $params['user_id'] );
517
518 // Get ID list of bookings, like '1' or '3,7,9' ----------------------------------------------------------------
519 if ( ! is_array( $booking_id_arr ) ) {
520 $booking_id_arr = array( $booking_id_arr );
521 }
522 $booking_is_csd = join( ',', $booking_id_arr );
523 $booking_is_csd = wpbc_clean_digit_or_csd( $booking_is_csd );
524
525
526 // Get reason of action --------------------------------------------------------------------------------------------
527 $action_reason = $params['reason_of_action']; // stripslashes( $params['reason_of_action'] ); // translate words like don\'t to don't
528
529 // Get reason of action --------------------------------------------------------------------------------------------
530 $is_trash_or_restore = $params['is_trash'];
531
532 // Is send email for this action ----------------------------------------------------------------------------------
533 $is_send_emeils = wpbc_ajx__user_request_option__is_send_emails( $params['user_id'] );
534
535
536 // -----------------------------------------------------------------------------------------------------------------
537
538 if ( empty( $booking_is_csd ) ) {
539 $after_action_result = false;
540 $after_action_message = __( 'No bookings have been selected. Please select one or more bookings.', 'booking' );
541
542 } else {
543 $after_action_result = true;
544 if ( $is_trash_or_restore == '1' ) {
545 $after_action_message = '<strong style="font-size: 1.4em;">' . count( explode( ',', $booking_is_csd ) ) .'</strong> '
546 . ( ( false === strpos( $booking_is_csd, ',' ) )
547 /* translators: 1: ... */
548 ? sprintf( __( 'Booking has been %1$s trashed %2$s', 'booking' ), '<strong>', '</strong>' )
549 /* translators: 1: ... */
550 : sprintf( __( 'Bookings have been %1$s trashed %2$s', 'booking' ) , '<strong>', '</strong>' )
551 )
552 . ' <span style="font-size:0.9em;">( ID = <strong>' . $booking_is_csd . '</strong> )</span>';
553 } else {
554 $after_action_message = '<strong style="font-size: 1.4em;">' . count( explode( ',', $booking_is_csd ) ) .'</strong> '
555 . ( ( false === strpos( $booking_is_csd, ',' ) )
556 /* translators: 1: ... */
557 ? sprintf( __( 'Booking has been set as %1$s restored %2$s', 'booking' ), '<strong>', '</strong>' )
558 /* translators: 1: ... */
559 : sprintf( __( 'Bookings have been set as %1$s restored %2$s', 'booking' ), '<strong>', '</strong>' )
560 )
561 . ' <span style="font-size:0.9em;">( ID = <strong>' . $booking_is_csd . '</strong> )</span>';
562 }
563 // SQL ---------------------------------------------------------------------------------------------------
564 global $wpdb;
565 // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.PreparedSQLPlaceholders.UnfinishedPrepare, WordPress.DB.PreparedSQL.InterpolatedNotPrepared
566 $prepared_sql = $wpdb->prepare( "UPDATE {$wpdb->prefix}booking SET trash = %s WHERE booking_id IN ({$booking_is_csd})", $is_trash_or_restore ); // FixIn: 10.12.1.5.
567 if ( $is_trash_or_restore == '1' ) {
568 // Trash
569 $my_trash_date = wpbc_datetime_localized( gmdate( 'Y-m-d H:i:s' ), 'Y-m-d H:i:s' );
570 // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.PreparedSQLPlaceholders.UnfinishedPrepare, WordPress.DB.PreparedSQL.InterpolatedNotPrepared
571 $prepared_sql = $wpdb->prepare( "UPDATE {$wpdb->prefix}booking SET trash = %s, is_trash = %s WHERE booking_id IN ({$booking_is_csd})", $is_trash_or_restore, $my_trash_date ); // FixIn: 10.12.1.5.
572 } else {
573 // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.PreparedSQLPlaceholders.UnfinishedPrepare, WordPress.DB.PreparedSQL.InterpolatedNotPrepared
574 $prepared_sql = $wpdb->prepare( "UPDATE {$wpdb->prefix}booking SET trash = %s, is_trash = NULL WHERE booking_id IN ({$booking_is_csd})", $is_trash_or_restore ); // FixIn: 10.12.1.5.
575 }
576
577 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.NotPrepared, PluginCheck.Security.DirectDB.UnescapedDBParameter
578 $after_action_result = $wpdb->query( $prepared_sql );
579 if ( false === $after_action_result ) {
580 $after_action_message = 'Error during updating to DB. File:' . __FILE__ . ' on line: ' . __LINE__;
581 } else {
582 $after_action_result = true;
583 }
584
585 // Update the Hash and Cost of the booking
586 $bk_id_arr = explode(',', $booking_is_csd ); // FixIn: 8.6.1.11.
587 foreach ( $bk_id_arr as $bk_id ) {
588 wpbc_hash__update_booking_hash( $bk_id );
589 }
590
591 // LOG ---------------------------------------------------------------------------------------------------------
592 $curr_user = get_user_by( 'id', (int) $params['user_id'] );
593 wpbc_db__add_log_info( explode( ',', $booking_is_csd ),
594 ( ( $is_trash_or_restore == '1' ) ? __( 'Trashed by:', 'booking' ) : __( 'Restored by:', 'booking' ) )
595 . ' ' . $curr_user->first_name . ' ' . $curr_user->last_name . ' (' . $curr_user->user_email . ')'
596 );
597
598 // :: ? :: Update 'is_new' status of bookings in Database
599 // wpbc_db_update_number_new_bookings( explode( ',', $booking_is_csd ), '0', $params['user_id'] );
600
601 // Just action hook for some other addons
602 do_action( 'wpbc_booking_action__trash', $booking_is_csd, $is_trash_or_restore ); // FixIn: 8.7.6.2.
603
604 // Emails ------------------------------------------------------------------------------------------------------
605 if ( ! empty( $is_send_emeils ) ) {
606
607 if ( $is_trash_or_restore == '1' ) {
608 wpbc_send_email_trash( $booking_is_csd, $is_send_emeils, $action_reason );
609 } else {
610 //wpbc_send_email_approved( $booking_is_csd, $is_send_emeils, $action_reason );
611 //wpbc_send_email_deny( $booking_is_csd, $is_send_emeils, $action_reason );
612 }
613 }
614 }
615
616 return array(
617 'after_action_result' => $after_action_result,
618 'after_action_message' => $after_action_message
619 );
620 }
621
622 /**
623 * Action: set booking as Approved | Pending
624 *
625 * @param $booking_id_arr array or int of booking ID
626 * @param $params array array of parameters: array( 'user_id' => 1, 'reason_of_action' => 'Because...', 'is_approve' => '1' )
627 *
628 * @return array
629 *
630 * Example:
631 * Approved:
632 $action_result = wpbc_booking_do_action__set_booking_approved_or_pending( $request_params['booking_id']
633 , array(
634 'user_id' => $user_id,
635 'reason_of_action' => $request_params['reason_of_action'],
636 'is_approve' => '1'
637 )
638 );
639 * Pending:
640 $action_result = wpbc_booking_do_action__set_booking_approved_or_pending( $request_params['booking_id']
641 , array(
642 'user_id' => $user_id,
643 'reason_of_action' => $request_params['reason_of_action'],
644 'is_approve' => '0'
645 )
646 );
647 */
648 function wpbc_booking_do_action__set_booking_approved_or_pending( $booking_id_arr, $params ){
649
650 /**
651 *
652 * For creation of new bookings or editing use something like this:
653 *
654 // Be sure to make load in Booking Listing this: wp_enqueue_script( 'wpbc-main-client', wpbc_plugin_url( '/js/client.js' ), array( 'wpbc-datepick' ), WP_BK_VERSION_NUM, array( 'in_footer' => WPBC_JS_IN_FOOTER ) );
655 new wpdev_booking(); // Define ability to work with shortcodes
656 $return_sh = do_shortcode('[booking type=1 nummonths=2]');
657 wp_send_json($return_sh); // Send calendar
658 */
659
660 make_bk_action('check_multiuser_params_for_client_side_by_user_id', $params['user_id'] );
661
662 // Get ID list of bookings, like '1' or '3,7,9' ----------------------------------------------------------------
663 if ( ! is_array( $booking_id_arr ) ) {
664 $booking_id_arr = array( $booking_id_arr );
665 }
666 $booking_id_csd = join( ',', $booking_id_arr );
667 $booking_id_csd = wpbc_clean_digit_or_csd( $booking_id_csd );
668
669
670 // Get reason of action --------------------------------------------------------------------------------------------
671 $action_reason = $params['reason_of_action']; // stripslashes( $params['reason_of_action'] ); // translate words like don\'t to don't
672
673 // Get reason of action --------------------------------------------------------------------------------------------
674 $is_approve_or_pending = $params['is_approve'];
675
676 // Is send email for this action ----------------------------------------------------------------------------------
677 $is_send_emeils = wpbc_ajx__user_request_option__is_send_emails( $params['user_id'] );
678
679
680 // -----------------------------------------------------------------------------------------------------------------
681
682 if ( empty( $booking_id_csd ) ) {
683 $after_action_result = false;
684 $after_action_message = __( 'No bookings have been selected. Please select one or more bookings.', 'booking' );
685
686 } else {
687 $after_action_result = true;
688 if ( $is_approve_or_pending == '1' ) {
689 $after_action_message = '<strong style="font-size: 1.4em;">' . count( explode( ',', $booking_id_csd ) ) .'</strong> '
690 . ( ( false === strpos( $booking_id_csd, ',' ) )
691 /* translators: 1: ... */
692 ? sprintf( __( 'Booking has been %1$s approved %2$s', 'booking' ), '<strong>', '</strong>' )
693 /* translators: 1: ... */
694 : sprintf( __( 'Bookings have been %1$s approved %2$s', 'booking' ) , '<strong>', '</strong>' )
695 )
696 . ' <span style="font-size:0.9em;">( ID = <strong>' . $booking_id_csd . '</strong> )</span>';
697 } else {
698 $after_action_message = '<strong style="font-size: 1.4em;">' . count( explode( ',', $booking_id_csd ) ) .'</strong> '
699 . ( ( false === strpos( $booking_id_csd, ',' ) )
700 /* translators: 1: ... */
701 ? sprintf( __( 'Booking has been set as %1$s pending %2$s', 'booking' ), '<strong>', '</strong>' )
702 /* translators: 1: ... */
703 : sprintf( __( 'Bookings have been set as %1$s pending %2$s', 'booking' ), '<strong>', '</strong>' )
704 )
705 . ' <span style="font-size:0.9em;">( ID = <strong>' . $booking_id_csd . '</strong> )</span>';
706 }
707 // SQL ---------------------------------------------------------------------------------------------------
708 global $wpdb;
709 // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.PreparedSQLPlaceholders.UnfinishedPrepare, WordPress.DB.PreparedSQL.InterpolatedNotPrepared
710 $prepared_sql = $wpdb->prepare( "UPDATE {$wpdb->prefix}bookingdates SET approved = %s WHERE booking_id IN ({$booking_id_csd})", $is_approve_or_pending );
711
712 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.NotPrepared, PluginCheck.Security.DirectDB.UnescapedDBParameter
713 $after_action_result = $wpdb->query( $prepared_sql );
714 if ( false === $after_action_result ) {
715 $after_action_message = 'Error during updating to DB. File:' . __FILE__ . ' on line: ' . __LINE__;
716 } else {
717 $after_action_result = true;
718 }
719
720 // LOG ---------------------------------------------------------------------------------------------------------
721 $curr_user = get_user_by( 'id', (int) $params['user_id'] );
722 wpbc_db__add_log_info( explode( ',', $booking_id_csd ),
723 ( ( $is_approve_or_pending == '1' ) ? __( 'Approved by:', 'booking' ) : __( 'Declined by:', 'booking' ) )
724 . ' ' . $curr_user->first_name . ' ' . $curr_user->last_name . ' (' . $curr_user->user_email . ')'
725 );
726
727 // Update 'is_new' status of bookings in Database
728 wpbc_db_update_number_new_bookings( explode( ',', $booking_id_csd ), '0', $params['user_id'] );
729
730 // Just action hook for some other addons
731 do_action( 'wpbc_booking_action__approved', $booking_id_csd, $is_approve_or_pending ); // FixIn: 8.7.6.1.
732
733 // Emails ------------------------------------------------------------------------------------------------------
734 if ( ! empty( $is_send_emeils ) ) {
735
736 if ( $is_approve_or_pending == '1' ) {
737 wpbc_send_email_approved( $booking_id_csd, $is_send_emeils, $action_reason );
738 } else {
739 wpbc_send_email_deny( $booking_id_csd, $is_send_emeils, $action_reason );
740 }
741 }
742
743 // Cancel other pending bookings for the same date ------------------------------------------------------------
744 if ( $is_approve_or_pending == '1' ) {
745 $all_bk_id_what_canceled = apply_bk_filter( 'cancel_pending_same_resource_bookings_for_specific_dates', false, $booking_id_csd );
746 }
747 }
748
749 return array(
750 'after_action_result' => $after_action_result,
751 'after_action_message' => $after_action_message
752 );
753 }
754
755 /**
756 * Action: booking Completely Delete
757 *
758 * @param $booking_id_arr array or int of booking ID
759 * @param $params array array of parameters: array( 'user_id' => 1, 'reason_of_action' => 'Because...' )
760 *
761 * @return array
762 *
763 * Example:
764 */
765 function wpbc_booking_do_action__delete_booking_completely( $booking_id_arr, $params ){
766
767 make_bk_action('check_multiuser_params_for_client_side_by_user_id', $params['user_id'] );
768
769 // Get ID list of bookings, like '1' or '3,7,9' ----------------------------------------------------------------
770 if ( ! is_array( $booking_id_arr ) ) {
771 $booking_id_arr = array( $booking_id_arr );
772 }
773 $booking_is_csd = join( ',', $booking_id_arr );
774 $booking_is_csd = wpbc_clean_digit_or_csd( $booking_is_csd );
775
776
777 // Get reason of action --------------------------------------------------------------------------------------------
778 $action_reason = $params['reason_of_action']; // stripslashes( $params['reason_of_action'] ); // translate words like don\'t to don't
779
780 // Is send email for this action ----------------------------------------------------------------------------------
781 $is_send_emeils = wpbc_ajx__user_request_option__is_send_emails( $params['user_id'] );
782
783
784 // -----------------------------------------------------------------------------------------------------------------
785
786 if ( empty( $booking_is_csd ) ) {
787 $after_action_result = false;
788 $after_action_message = __( 'No bookings have been selected. Please select one or more bookings.', 'booking' );
789
790 } else {
791 $after_action_result = true;
792 $bookings_count = '<strong style="font-size: 1.4em;">' . count( explode( ',', $booking_is_csd ) ) .'</strong> ';
793 $after_action_message = $bookings_count . ' '
794 . ( ( false === strpos( $booking_is_csd, ',' ) )
795 /* translators: 1: ... */
796 ? strtolower( sprintf( __( 'Booking has been %1$s deleted %2$s', 'booking' ), '<strong>', '</strong>' ) )
797 /* translators: 1: ... */
798 : strtolower( sprintf( __( 'Bookings have been %1$s deleted %2$s', 'booking' ) , '<strong>', '</strong>' ) )
799 )
800 . ' <span style="font-size:0.9em;">( ID = <strong>' . implode( ', ', explode( ',', $booking_is_csd ) ) . '</strong> )</span>';
801
802 // LOG ---------------------------------------------------------------------------------------------------------
803 $curr_user = get_user_by( 'id', (int) $params['user_id'] );
804 wpbc_db__add_log_info( explode( ',', $booking_is_csd ),
805 __( 'Deleted by:', 'booking' )
806 . ' ' . $curr_user->first_name . ' ' . $curr_user->last_name . ' (' . $curr_user->user_email . ')'
807 );
808
809 // Just action hook for some other addons
810 do_action( 'wpbc_booking_action__delete', $booking_is_csd ); // FixIn: 8.7.6.3.
811
812 // Emails ------------------------------------------------------------------------------------------------------
813 if ( ! empty( $is_send_emeils ) ) {
814
815 wpbc_send_email_deleted( $booking_is_csd, $is_send_emeils, $action_reason );
816 }
817
818 // SQL ---------------------------------------------------------------------------------------------------
819 global $wpdb;
820
821 // Dates
822 $prepared_sql = "DELETE FROM {$wpdb->prefix}bookingdates WHERE booking_id IN ({$booking_is_csd})";
823 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.NotPrepared, PluginCheck.Security.DirectDB.UnescapedDBParameter
824 $after_action_result = $wpdb->query( $prepared_sql );
825 if ( false === $after_action_result ) {
826 $after_action_message = 'Error during deleting dates in DB. File:' . __FILE__ . ' on line: ' . __LINE__;
827 } else {
828 $after_action_result = true;
829 }
830 // Bookings
831 $prepared_sql = "DELETE FROM {$wpdb->prefix}booking WHERE booking_id IN ({$booking_is_csd})";
832 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.NotPrepared, PluginCheck.Security.DirectDB.UnescapedDBParameter
833 $after_action_result = $wpdb->query( $prepared_sql );
834 if ( false === $after_action_result ) {
835 $after_action_message = 'Error during deleting bookings in DB. File:' . __FILE__ . ' on line: ' . __LINE__;
836 } else {
837 $after_action_result = true;
838 }
839
840 }
841
842 return array(
843 'after_action_result' => $after_action_result,
844 'after_action_message' => $after_action_message
845 );
846 }
847
848 /**
849 * Action: set booking as Read (Old) | Unread (New)
850 *
851 * @param $booking_id_arr array or int of booking ID
852 * @param $params array array of parameters: array( 'user_id' => 1, 'is_new' => '1' )
853 *
854 * @return array
855 *
856 * Example:
857 $action_result = wpbc_booking_do_action__set_booking_as_read_unread( $request_params['booking_id']
858 , array(
859 'user_id' => $user_id,
860 'is_new' => '0'
861 )
862 );
863
864 */
865 function wpbc_booking_do_action__set_booking_as_read_unread( $booking_id_arr, $params ){
866
867 make_bk_action('check_multiuser_params_for_client_side_by_user_id', $params['user_id'] );
868
869 // Get ID list of bookings, like '1' or '3,7,9' ----------------------------------------------------------------
870 if ( ! is_array( $booking_id_arr ) ) {
871 $booking_id_arr = array( $booking_id_arr );
872 }
873 $booking_id_csd = join( ',', $booking_id_arr );
874 $booking_id_csd = wpbc_clean_digit_or_csd( $booking_id_csd );
875
876 // Get reason of action --------------------------------------------------------------------------------------------
877 $is_new = $params['is_new'];
878
879 // Is send email for this action ----------------------------------------------------------------------------------
880 $is_send_emeils = wpbc_ajx__user_request_option__is_send_emails( $params['user_id'] );
881
882 // -----------------------------------------------------------------------------------------------------------------
883
884 if ( empty( $booking_id_csd ) ) {
885 $after_action_result = false;
886 $after_action_message = __( 'No bookings have been selected. Please select one or more bookings.', 'booking' );
887
888 } else {
889 $after_action_result = true;
890 if ( $is_new == '1' ) {
891 $after_action_message = ( ( false === strpos( $booking_id_csd, ',' ) )
892 /* translators: 1: ... */
893 ? sprintf( __( 'Booking has been set as %1$s new %2$s', 'booking' ), '<strong>', '</strong>' )
894 /* translators: 1: ... */
895 : sprintf( __( 'Bookings have been set as %1$s new %2$s', 'booking' ) , '<strong>', '</strong>' )
896 )
897 . ' <span style="font-size:0.9em;">( ID = <strong>' . (( '-1' == $booking_id_csd ) ? __( 'all', 'booking' ) : $booking_id_csd) . '</strong> )</span>';
898 } else {
899 $after_action_message = ( ( false === strpos( $booking_id_csd, ',' ) )
900 /* translators: 1: ... */
901 ? sprintf( __( 'The booking has been marked as %1$s read %2$s', 'booking' ), '<strong>', '</strong>' )
902 /* translators: 1: ... */
903 : sprintf( __( 'Bookings have been marked as %1$s read %2$s', 'booking' ), '<strong>', '</strong>' )
904 )
905 . ' <span style="font-size:0.9em;">( ID = <strong>' . (( '-1' == $booking_id_csd ) ? __( 'all', 'booking' ) : $booking_id_csd) . '</strong> )</span>';
906 }
907 // SQL ---------------------------------------------------------------------------------------------------
908 global $wpdb;
909 if ('-1' == $booking_id_csd ){
910 $prepared_sql = $wpdb->prepare( "UPDATE {$wpdb->prefix}booking SET is_new = %s", $is_new ); // FixIn: 10.12.1.5.
911
912 $prepared_sql .= " WHERE ( 1 = 1 ) ";
913 // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.PreparedSQLPlaceholders.UnfinishedPrepare, WordPress.DB.PreparedSQL.InterpolatedNotPrepared
914 $prepared_sql = apply_bk_filter('update_where_sql_for_getting_bookings_in_multiuser', $prepared_sql );
915 } else {
916 // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.PreparedSQLPlaceholders.UnfinishedPrepare, WordPress.DB.PreparedSQL.InterpolatedNotPrepared
917 $prepared_sql = $wpdb->prepare( "UPDATE {$wpdb->prefix}booking SET is_new = %s WHERE booking_id IN ({$booking_id_csd})", $is_new ); // FixIn: 10.12.1.5.
918 }
919 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.NotPrepared, PluginCheck.Security.DirectDB.UnescapedDBParameter
920 $after_action_result = $wpdb->query( $prepared_sql );
921 if ( false === $after_action_result ) {
922 $after_action_message = 'Error during updating to DB. File:' . __FILE__ . ' on line: ' . __LINE__;
923 } else {
924 $after_action_result = true;
925 }
926
927 // LOG ---------------------------------------------------------------------------------------------------------
928 $curr_user = get_user_by( 'id', (int) $params['user_id'] );
929 wpbc_db__add_log_info( explode( ',', $booking_id_csd ),
930 ( ( $is_new == '1' ) ? __( 'Set as unread by:', 'booking' ) : __( 'Set as read by:', 'booking' ) )
931 . ' ' . $curr_user->first_name . ' ' . $curr_user->last_name . ' (' . $curr_user->user_email . ')'
932 );
933
934 // Just action hook for some other addons
935 do_action( 'wpbc_booking_action__changed_new_status', $booking_id_csd, $is_new ); // FixIn: 8.7.6.1.
936
937 // Emails ------------------------------------------------------------------------------------------------------
938 if ( ! empty( $is_send_emeils ) ) {
939
940 if ( $is_new == '1' ) {
941 //wpbc_send_email_approved( $booking_id_csd, $is_send_emeils, $action_reason );
942 } else {
943 //wpbc_send_email_deny( $booking_id_csd, $is_send_emeils, $action_reason );
944 }
945 }
946 }
947
948 return array(
949 'after_action_result' => $after_action_result,
950 'after_action_message' => $after_action_message
951 );
952 }
953
954 /**
955 * Action: Emty Trash
956 *
957 * @param $params array array of parameters: array( 'user_id' => 1 )
958 *
959 * @return array
960 *
961 * Example:
962 */
963 function wpbc_booking_do_action__empty_trash( $params ){
964
965 make_bk_action('check_multiuser_params_for_client_side_by_user_id', $params['user_id'] );
966
967 // Is send email for this action ----------------------------------------------------------------------------------
968 $is_send_emeils = wpbc_ajx__user_request_option__is_send_emails( $params['user_id'] );
969
970 // Get bookings ID to delete -------------------------------------------------------------------------------
971 global $wpdb;
972
973 $sql = "SELECT * FROM {$wpdb->prefix}booking as bk WHERE bk.trash = 1"; // FixIn: 10.12.1.5.
974
975 $sql = apply_bk_filter( 'update_where_sql_for_getting_bookings_in_multiuser', $sql, $params['user_id'] ); // Get booking resources of this user only: $user_id
976
977 $max_bookings_to_erase = 1000;
978 $sql .= " LIMIT 0, " . $max_bookings_to_erase;
979
980 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.NotPrepared, PluginCheck.Security.DirectDB.UnescapedDBParameter
981 $bookings_in_trash = $wpdb->get_results( $sql );
982
983 $bookings_id_in_trash_arr = array();
984
985 foreach ( $bookings_in_trash as $booking_obj ) {
986 $bookings_id_in_trash_arr[] = $booking_obj->booking_id;
987 }
988 $booking_is_csd = implode( ',', $bookings_id_in_trash_arr );
989
990 // Empty trash ------------------------------------------------------------------------------------------------
991
992 if ( empty( $booking_is_csd ) ) {
993 $after_action_result = false;
994 $after_action_message = __( 'No bookings in trash to erase.', 'booking' );
995
996 } else {
997 $after_action_result = true;
998 if ( count( $bookings_id_in_trash_arr ) < $max_bookings_to_erase ) {
999 $after_action_message = sprintf( __( 'Trash has been erased.', 'booking' ) , '<strong>', '</strong>' )
1000 . ' <span style="font-size:0.9em;">( ID = <strong>' . substr( $booking_is_csd, 0 , 500 ) . '</strong> )</span>';
1001 } else {
1002 /* translators: 1: ... */
1003 $after_action_message = sprintf( __( 'From trash has been erased %s bookings.', 'booking' ) , '<strong> ' . count( $bookings_id_in_trash_arr ) . ' </strong> ' ) ;
1004 }
1005
1006 // LOG -----------------------------------------------------------------------------------------------------
1007 // $curr_user = get_user_by( 'id', (int) $params['user_id'] );
1008 // wpbc_db__add_log_info( explode( ',', $booking_is_csd ),
1009 // __( 'Deleted by:', 'booking' )
1010 // . ' ' . $curr_user->first_name . ' ' . $curr_user->last_name . ' (' . $curr_user->user_email . ')'
1011 // );
1012
1013 // Just action hook for some other addons
1014 do_action( 'wpbc_booking_action__empty_trash' ); // FixIn: 8.7.6.3.
1015
1016 // Emails ------------------------------------------------------------------------------------------------------
1017 if ( ! empty( $is_send_emeils ) ) {
1018
1019 // wpbc_send_email_deleted( $booking_is_csd, $is_send_emeils, __( 'Empty Trash', 'booking' ) );
1020 }
1021
1022 // SQL ---------------------------------------------------------------------------------------------------
1023
1024 // Dates
1025 $prepared_sql = "DELETE FROM {$wpdb->prefix}bookingdates WHERE booking_id IN ({$booking_is_csd})";
1026 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.NotPrepared, PluginCheck.Security.DirectDB.UnescapedDBParameter
1027 $after_action_result = $wpdb->query( $prepared_sql );
1028 if ( false === $after_action_result ) {
1029 $after_action_message = 'Error during deleting dates in DB. File:' . __FILE__ . ' on line: ' . __LINE__;
1030 } else {
1031 $after_action_result = true;
1032 }
1033 // Bookings
1034 $prepared_sql = "DELETE FROM {$wpdb->prefix}booking WHERE booking_id IN ({$booking_is_csd})";
1035 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.NotPrepared, PluginCheck.Security.DirectDB.UnescapedDBParameter
1036 $after_action_result = $wpdb->query( $prepared_sql );
1037 if ( false === $after_action_result ) {
1038 $after_action_message = 'Error during deleting bookings in DB. File:' . __FILE__ . ' on line: ' . __LINE__;
1039 } else {
1040 $after_action_result = true;
1041 }
1042
1043 }
1044
1045 return array(
1046 'after_action_result' => $after_action_result,
1047 'after_action_message' => $after_action_message
1048 );
1049 }
1050
1051 /**
1052 * Action: save booking Remark
1053 *
1054 * @param $booking_id_arr array or int of booking ID
1055 * @param $params array array of parameters: array( 'user_id' => 1, 'remark' => 'Because...')
1056 *
1057 * @return array
1058 *
1059 * Example:
1060 */
1061 function wpbc_booking_do_action__set_booking_note( $booking_id_arr, $params ){
1062
1063 make_bk_action('check_multiuser_params_for_client_side_by_user_id', $params['user_id'] );
1064
1065 // Get ID list of bookings, like '1' or '3,7,9' ------------------------------------------------------------
1066 if ( ! is_array( $booking_id_arr ) ) {
1067 $booking_id_arr = array( $booking_id_arr );
1068 }
1069 $booking_id_csd = join( ',', $booking_id_arr );
1070 $booking_id_csd = wpbc_clean_digit_or_csd( $booking_id_csd );
1071
1072 // Get remark --------------------------------------------------------------------------------------------------
1073 $remark_text = $params['remark']; // stripslashes( $params['reason_of_action'] ); // translate words like don\'t to don't
1074
1075 // Is send email for this action ------------------------------------------------------------------------------
1076 // $is_send_emeils = wpbc_ajx__user_request_option__is_send_emails( $params['user_id'] );
1077
1078
1079 // -----------------------------------------------------------------------------------------------------------------
1080
1081 if ( empty( $booking_id_csd ) ) {
1082 $after_action_result = false;
1083 $after_action_message = __( 'No bookings have been selected. Please select one or more bookings.', 'booking' );
1084
1085 } else {
1086 $after_action_result = true;
1087 $after_action_message = __( 'Note has been saved', 'booking' )
1088 . ' <span style="font-size:0.9em;">( ID = <strong>' . $booking_id_csd . '</strong> )</span>';
1089 // SQL ---------------------------------------------------------------------------------------------------
1090 global $wpdb;
1091 // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.PreparedSQLPlaceholders.UnfinishedPrepare, WordPress.DB.PreparedSQL.InterpolatedNotPrepared
1092 $prepared_sql = $wpdb->prepare( "UPDATE {$wpdb->prefix}booking SET remark = %s WHERE booking_id IN ({$booking_id_csd})", $remark_text );
1093 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.NotPrepared, PluginCheck.Security.DirectDB.UnescapedDBParameter
1094 $after_action_result = $wpdb->query( $prepared_sql );
1095 if ( false === $after_action_result ) {
1096 $after_action_message = 'Error during updating to DB. File:' . __FILE__ . ' on line: ' . __LINE__;
1097 } else {
1098 $after_action_result = true;
1099 }
1100
1101 // LOG ---------------------------------------------------------------------------------------------------------
1102 if (0) {
1103 $curr_user = get_user_by( 'id', (int) $params['user_id'] );
1104 wpbc_db__add_log_info( explode( ',', $booking_id_csd ),
1105 __( 'Note saved by:', 'booking' )
1106 . ' ' . $curr_user->first_name . ' ' . $curr_user->last_name . ' (' . $curr_user->user_email . ')'
1107 );
1108 }
1109
1110 // Just action hook for some other addons
1111 do_action( 'wpbc_booking_action__note_saved', $booking_id_csd, $remark_text );
1112
1113 // Emails ------------------------------------------------------------------------------------------------------
1114 if ( 0 ) {
1115 if ( ! empty( $is_send_emeils ) ) {
1116 wpbc_send_email_approved( $booking_id_csd, $is_send_emeils, $remark_text );
1117 }
1118 }
1119 }
1120
1121 return array(
1122 'after_action_result' => $after_action_result,
1123 'after_action_message' => $after_action_message
1124 );
1125 }
1126
1127 /**
1128 * Action: change Booking Resource
1129 *
1130 * @param $booking_id_arr array or int of booking ID
1131 * @param $selected_resource_id int of booking resource
1132 * @param $params array array of parameters: array( 'user_id' => 1 )
1133 *
1134 * @return array
1135 *
1136 * Example:
1137 */
1138 function wpbc_booking_do_action__change_booking_resource( $booking_id_arr, $selected_resource_id, $params ) {
1139
1140 make_bk_action('check_multiuser_params_for_client_side_by_user_id', $params['user_id'] );
1141
1142 // Get ID list of bookings, like '1' or '3,7,9' ----------------------------------------------------------------
1143 if ( ! is_array( $booking_id_arr ) ) {
1144 $booking_id_arr = array( $booking_id_arr );
1145 }
1146 $booking_id_csd = join( ',', $booking_id_arr );
1147 $booking_id_csd = wpbc_clean_digit_or_csd( $booking_id_csd );
1148
1149 // ID of booking resource ------------------------------------------------------------------------------------------
1150 $selected_resource_id = intval($selected_resource_id);
1151
1152 // Is send email for this action ----------------------------------------------------------------------------------
1153 $is_send_emeils = wpbc_ajx__user_request_option__is_send_emails( $params['user_id'] );
1154
1155 // -----------------------------------------------------------------------------------------------------------------
1156
1157 if ( empty( $booking_id_csd ) ) {
1158 $after_action_result = false;
1159 $after_action_message = __( 'No bookings have been selected. Please select one or more bookings.', 'booking' );
1160
1161 } else {
1162 $after_action_result = true;
1163
1164 $after_action_message = ( ( false === strpos( $booking_id_csd, ',' ) )
1165 /* translators: 1: ... */
1166 ? sprintf( __( 'Booking has been changed %1$s booking resource %2$s', 'booking' ), '<strong>', '</strong>' )
1167 /* translators: 1: ... */
1168 : sprintf( __( 'Bookings have been changed %1$s booking resource %2$s', 'booking' ), '<strong>', '</strong>' )
1169 )
1170 . ' <span style="font-size:0.9em;">( ID = <strong>' . $booking_id_csd . '</strong> )</span>';
1171
1172
1173 $work_booking_id_arr = explode( ',', $booking_id_csd );
1174
1175 foreach ( $work_booking_id_arr as $selected_booking_id ) {
1176
1177 // SQL ---------------------------------------------------------------------------------------------------
1178 list( $after_action_result, $after_action_message, $formdata_new ) = wpbc__sql__change_booking_resource_for_booking( $selected_booking_id, $selected_resource_id );
1179
1180 if ( $after_action_result ) {
1181 // LOG ---------------------------------------------------------------------------------------------------------
1182 $curr_user = get_user_by( 'id', (int) $params['user_id'] );
1183 wpbc_db__add_log_info( explode( ',', $selected_booking_id ),
1184 __( 'Booking resource changed by:', 'booking' )
1185 . ' ' . $curr_user->first_name . ' ' . $curr_user->last_name . ' (' . $curr_user->user_email . ')'
1186 );
1187
1188 // Just action hook for some other addons
1189 do_action( 'wpbc_booking_action__change_booking_resource', $selected_booking_id, $selected_resource_id );
1190
1191 // Emails ------------------------------------------------------------------------------------------------------
1192 if ( ! empty( $is_send_emeils ) ) {
1193 wpbc_send_email_modified( $selected_booking_id, $selected_resource_id, $formdata_new );
1194 }
1195 }
1196 }
1197 }
1198
1199 return array(
1200 'after_action_result' => $after_action_result,
1201 'after_action_message' => $after_action_message
1202 );
1203
1204 }
1205
1206 /**
1207 * Change booking resource for specific booking -- SQL manipulation
1208 * @param $selected_booking_id
1209 * @param $selected_resource_id
1210 *
1211 * @return array
1212 */
1213 function wpbc__sql__change_booking_resource_for_booking( $selected_booking_id, $selected_resource_id ){
1214
1215 global $wpdb;
1216
1217 $booking_id = intval( $selected_booking_id );
1218 $resource_id = intval( $selected_resource_id );
1219 $db_form_data_new = '';
1220
1221 ////////////////////////////////////////////////////////////////////////////////////////////////////////////
1222 // 1.Get dates of SOURCE booking
1223 ////////////////////////////////////////////////////////////////////////////////////////////////////////////
1224 if ( 1 ) {
1225 // 1.1.Get booking data of SOURCE booking
1226 $sql = $wpdb->prepare( "SELECT * FROM {$wpdb->prefix}booking as bk WHERE booking_id = %d ", $booking_id );
1227
1228 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.NotPrepared, PluginCheck.Security.DirectDB.UnescapedDBParameter
1229 $res = $wpdb->get_row( $sql );
1230
1231 $db_form_data_old = $res->form;
1232 $resource_id_old = $res->booking_type;
1233
1234 // 1.2. Get dates of SOURCE booking
1235 $sql = $wpdb->prepare( "SELECT * FROM {$wpdb->prefix}bookingdates as dt WHERE booking_id = %d ORDER BY booking_date ASC ", $booking_id );
1236 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.NotPrepared, PluginCheck.Security.DirectDB.UnescapedDBParameter
1237 $old_resource_dates_array = $wpdb->get_results( $sql );
1238 }
1239
1240
1241 //TODO: 2023-10-03 14:49 this is new workflow have to be:
1242 if (0){
1243 $booking_p = array(
1244 'dates' => TRANSFORM_IT( $old_resource_dates_array ) // -> array( '2017-06-23 14:00:01', '2017-06-24 00:00:00', '2017-06-25', '2017-06-26 12:00:02' )
1245 , 'resource_id' => $resource_id
1246 , 'params' => array() // 'is_use_booking_recurrent_time' => false ) // Commented, because get from Booking > Settings General page
1247 );
1248 $is_dates_booked = wpbc_api_is_dates_booked( $booking_p[ 'dates' ], $booking_p[ 'resource_id' ], $booking_p[ 'params' ] );
1249 }
1250
1251 ////////////////////////////////////////////////////////////////////////////////////////////////////////////
1252 // 2. Get bookings of selected booking resource - checking if some dates there is booked or not
1253 ////////////////////////////////////////////////////////////////////////////////////////////////////////////
1254 $exist_dates_results = wpbc_get_booking_dates_in_resource_for_folowing_dates( $old_resource_dates_array , $resource_id );
1255
1256
1257 if ( ( count( $exist_dates_results ) == 3 ) && ( false === $exist_dates_results[0] ) ){
1258 // // ERROR :: number of check in/dates does not equal to number of check out dates.
1259 return $exist_dates_results;
1260 }
1261
1262 if ( get_bk_option('booking_change_resource_skip_checking') === 'On' ) { // FixIn: 8.4.5.4.
1263 $is_date_time_booked = false;
1264 } else {
1265 $is_date_time_booked = wpbc_check_dates_intersections( $old_resource_dates_array, $exist_dates_results );
1266 }
1267
1268 if ( $is_date_time_booked ) {
1269
1270 $after_action_result = false;
1271 $after_action_message = __( 'Warning! The resource was not changed. Current dates are already booked there.', 'booking' );
1272
1273 } else { // Possible to change
1274
1275 $db_form_data_new = wpbc_update_resource_id_in_dbformatted_booking_data( $db_form_data_old, $resource_id_old, $resource_id );
1276
1277 // Update // FixIn: 10.12.1.5.
1278 $update_sql = $wpdb->prepare( "UPDATE {$wpdb->prefix}booking SET form=%s, booking_type=%d WHERE booking_id=%d;"
1279 , $db_form_data_new, $resource_id, $booking_id );
1280 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.NotPrepared, PluginCheck.Security.DirectDB.UnescapedDBParameter
1281 if ( false === $wpdb->query( $update_sql ) ) {
1282 $after_action_result = false;
1283 $after_action_message = get_debuge_error( 'Error during updating booking reource type in BD', __FILE__, __LINE__ );
1284
1285 return array( $after_action_result, $after_action_message, $db_form_data_new );
1286 }
1287
1288
1289 if ( class_exists( 'wpdev_bk_biz_l' ) ) {
1290 $update_sql = $wpdb->prepare( "UPDATE {$wpdb->prefix}bookingdates SET type_id=NULL WHERE booking_id=%d ", $booking_id );
1291 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.NotPrepared, PluginCheck.Security.DirectDB.UnescapedDBParameter
1292 if ( false === $wpdb->query( $update_sql ) ) {
1293 $after_action_result = false;
1294 $after_action_message = get_debuge_error( 'Error during updating dates type in BD', __FILE__, __LINE__ );
1295
1296 return array( $after_action_result, $after_action_message, $db_form_data_new );
1297 }
1298 }
1299
1300 $booking_resources_arr = wpbc_ajx_get_all_booking_resources_arr();
1301 $after_action_result = true;
1302 /* translators: 1: ... */
1303 $after_action_message = sprintf( __( 'Booking %1$s has been changed booking resource from %2$s to %3$s', 'booking' )
1304 , '<strong>[ID=' . $booking_id . ']</strong>'
1305 , '<strong>' . wpbc_lang( $booking_resources_arr[ $resource_id_old ]['title'] ) . '</strong>'
1306 , '<strong>' . wpbc_lang( $booking_resources_arr[ $resource_id ]['title'] ) . '</strong>'
1307 );
1308
1309 // Everything Cool :) - booking resource changed
1310 }
1311
1312 return array( $after_action_result, $after_action_message , $db_form_data_new );
1313 }
1314
1315 /**
1316 * Get booking dates (bookings obj) of selected booking resource - checking if some dates there is booked or not
1317 *
1318 * @param $old_resource_dates_array array of OBJ with ..->booking_date
1319 * @param int $resource_id Resource ID, where we get dates.
1320 *
1321 * @return array array of booking OBJ with ..->booking_date
1322 */
1323 function wpbc_get_booking_dates_in_resource_for_folowing_dates( $old_resource_dates_array , $resource_id ){
1324
1325 global $wpdb;
1326
1327 $dates_sql_between = '';
1328 $check_in_dates_arr = array();
1329 $check_out_dates_arr = array();
1330
1331 if ( 'On' === get_bk_option( 'booking_recurrent_time' ) ) { // If we are using recurrent time slots ?
1332
1333 foreach ( $old_resource_dates_array as $k => $v ) {
1334
1335 if ( ':02' == substr( $v->booking_date, - 3 ) ) {
1336 $check_out_dates_arr[] = $v->booking_date;
1337 }
1338 if ( ':01' == substr( $v->booking_date, - 3 ) ) {
1339 $check_in_dates_arr[] = $v->booking_date;
1340 }
1341 }
1342
1343 if ( count( $check_out_dates_arr ) == count( $check_in_dates_arr ) ) {
1344 $dates_sql_between_arr = array();
1345 foreach ( $check_in_dates_arr as $k => $v ) {
1346
1347 $dates_sql_between_arr [] = ' ( dt.booking_date BETWEEN "' . $check_in_dates_arr[ $k ] . '" AND "' . $check_out_dates_arr[ $k ] . '" ) ';
1348 }
1349 $dates_sql_between = implode( 'OR', $dates_sql_between_arr );
1350
1351 //TODO: remove (), if only 1 element in array
1352
1353 } else {
1354 // ERROR :: number of check in/dates does not equal to number of check out dates.
1355 $after_action_result = false;
1356 $after_action_message = '<strong>Error</strong>. Number of check in times of booking dates does not equal to number of check out days.'
1357 . '<br>Check in dates: ' . implode( ', ', $check_in_dates_arr )
1358 . '<br>Check out dates: ' . implode( ', ', $check_out_dates_arr );
1359
1360 return array( $after_action_result, $after_action_message, '' );
1361 }
1362 }
1363
1364 if ( '' == $dates_sql_between ) {
1365
1366 $temp_check_in = $old_resource_dates_array[0]->booking_date;
1367 $temp_check_out = $old_resource_dates_array[ ( count( $old_resource_dates_array ) - 1 ) ]->booking_date;
1368
1369 if ( ':02' != substr( $temp_check_out, - 3 ) ) {
1370 $temp_check_out = gmdate( 'Y-m-d H:i:s', strtotime( '+1 day -1 second', strtotime( $temp_check_out ) ) );
1371 }
1372
1373 $dates_sql_between .= ' dt.booking_date BETWEEN "' . $temp_check_in . '" AND "' . $temp_check_out . '" ';
1374 }
1375
1376
1377 $sql = $wpdb->prepare( "SELECT * FROM {$wpdb->prefix}booking as bk
1378 INNER JOIN {$wpdb->prefix}bookingdates as dt
1379 ON bk.booking_id = dt.booking_id
1380 WHERE bk.trash != 1 AND bk.booking_type = %d", $resource_id );
1381 $sql .= " AND ( {$dates_sql_between} ) ";
1382
1383 // In BL version its does not check for booking belonging to several booking resources
1384 if ( class_exists( 'wpdev_bk_biz_l' ) ) {
1385 $sql .= " OR bk.booking_id IN ( "
1386 . " SELECT DISTINCT booking_id FROM {$wpdb->prefix}bookingdates as dtt
1387 WHERE dtt.type_id = {$resource_id} "
1388 //."AND DATE(dt.booking_date) IN ( {$dates_string} )"
1389 . " AND ( " . str_replace( 'dt.', 'dtt.', $dates_sql_between ) . " ) "
1390 . ") ";
1391 }
1392 $sql .= " ORDER BY bk.booking_id DESC, dt.booking_date ASC ";
1393
1394 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.NotPrepared, PluginCheck.Security.DirectDB.UnescapedDBParameter
1395 $exist_dates_results = $wpdb->get_results( $sql );
1396
1397 // We have found only intersected dates. Now we need to get all dates from such bookings, for having correct "Start and end time times for the booking"
1398 // and does not add some "start time at the begining of the day inside of wpbc_check_dates_intersections( ) function
1399 if ( count( $exist_dates_results ) > 0 ) {
1400
1401 // Get ID of all bookings that inside of this interval
1402 $my_booking_id_arr = [];
1403 foreach ( $exist_dates_results as $key => $booking_obj ) {
1404 $my_booking_id_arr[] = $booking_obj->booking_id;
1405 }
1406 // Get all dates of such bookings (not only intersected!
1407 $sql = $wpdb->prepare( "SELECT * FROM {$wpdb->prefix}booking as bk
1408 INNER JOIN {$wpdb->prefix}bookingdates as dt
1409 ON bk.booking_id = dt.booking_id
1410 WHERE bk.booking_id IN (" . implode( ',', $my_booking_id_arr ) . ") AND bk.trash != 1 AND bk.booking_type = %d", $resource_id ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
1411 $sql .= " ORDER BY bk.booking_id DESC, dt.booking_date ASC ";
1412
1413 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.NotPrepared, PluginCheck.Security.DirectDB.UnescapedDBParameter
1414 $exist_dates_results = $wpdb->get_results( $sql );
1415 }
1416
1417 return $exist_dates_results;
1418 }
1419
1420 /**
1421 * Update "Content of booking fields data" from old booking resource id SUFFIX to new booking Resource ID
1422 *
1423 * @param string $db_form_data_old
1424 * @param int $resource_id_old
1425 * @param int $resource_id_new
1426 *
1427 * @return void
1428 */
1429 function wpbc_update_resource_id_in_dbformatted_booking_data( $db_form_data_old, $resource_id_old, $resource_id_new ) {
1430
1431 $db_form_data_new = array();
1432
1433 $form_data_arr = explode( '~', $db_form_data_old );
1434 $fields_count = count( $form_data_arr );
1435
1436 for ( $i = 0; $i < $fields_count; $i ++ ) {
1437
1438 list( $type, $element_name, $value ) = explode( '^', $form_data_arr[ $i ] );
1439
1440 if ( substr( $element_name, - 2 ) == '[]' ) {
1441 $element_name = str_replace( '[]', '', $element_name );
1442 }
1443
1444 $element_name = substr( $element_name, 0, - 1 * strlen( $resource_id_old ) ) . $resource_id_new; // Change resource ID in field
1445
1446 $db_form_data_new[] = $type . '^' . $element_name . '^' . $value;
1447 }
1448
1449 return implode( '~', $db_form_data_new );
1450 }
1451
1452 /**
1453 * Action: Duplicate Booking into other Resource
1454 *
1455 * @param $booking_id_arr array or int of booking ID
1456 * @param $selected_resource_id int of booking resource
1457 * @param $params array array of parameters: array( 'user_id' => 1 )
1458 *
1459 * @return array
1460 *
1461 * Example:
1462 */
1463 function wpbc_booking_do_action__duplicate_booking_to_other_resource( $booking_id_arr, $selected_resource_id, $params ) {
1464
1465 make_bk_action('check_multiuser_params_for_client_side_by_user_id', $params['user_id'] );
1466
1467 // Get ID list of bookings, like '1' or '3,7,9' ----------------------------------------------------------------
1468 if ( ! is_array( $booking_id_arr ) ) {
1469 $booking_id_arr = array( $booking_id_arr );
1470 }
1471 $booking_id_csd = join( ',', $booking_id_arr );
1472 $booking_id_csd = wpbc_clean_digit_or_csd( $booking_id_csd );
1473
1474 // ID of booking resource ------------------------------------------------------------------------------------------
1475 $selected_resource_id = intval($selected_resource_id);
1476
1477 // Is send email for this action ----------------------------------------------------------------------------------
1478 $is_send_emeils = wpbc_ajx__user_request_option__is_send_emails( $params['user_id'] );
1479
1480 // -----------------------------------------------------------------------------------------------------------------
1481
1482 if ( empty( $booking_id_csd ) ) {
1483 $after_action_result = false;
1484 $after_action_message = __( 'No bookings have been selected. Please select one or more bookings.', 'booking' );
1485
1486 } else {
1487 $after_action_result = true;
1488
1489 $after_action_message = ( ( false === strpos( $booking_id_csd, ',' ) )
1490 /* translators: 1: ... */
1491 ? sprintf( __( 'Booking has been %1$s duplicated %2$s', 'booking' ), '<strong>', '</strong>' )
1492 /* translators: 1: ... */
1493 : sprintf( __( 'Bookings have been %1$s duplicated %2$s', 'booking' ), '<strong>', '</strong>' )
1494 )
1495 . ' <span style="font-size:0.9em;">( ID = <strong>' . $booking_id_csd . '</strong> )</span>';
1496
1497
1498 $work_booking_id_arr = explode( ',', $booking_id_csd );
1499
1500 foreach ( $work_booking_id_arr as $selected_booking_id ) {
1501
1502 // SQL ---------------------------------------------------------------------------------------------------
1503 list( $after_action_result, $after_action_message, $formdata_new ) = wpbc__sql__duplicate_booking_to_other_resource_for_booking( $selected_booking_id, $selected_resource_id, $params );
1504
1505 if ( $after_action_result ) {
1506 // LOG ---------------------------------------------------------------------------------------------------------
1507 $curr_user = get_user_by( 'id', (int) $params['user_id'] );
1508 wpbc_db__add_log_info( explode( ',', $selected_booking_id ),
1509 __( 'Booking resource changed by:', 'booking' )
1510 . ' ' . $curr_user->first_name . ' ' . $curr_user->last_name . ' (' . $curr_user->user_email . ')'
1511 );
1512
1513 // Just action hook for some other addons
1514 do_action( 'wpbc_booking_action__duplicate_booking_to_other_resource', $selected_booking_id, $selected_resource_id );
1515
1516 // Emails ------------------------------------------------------------------------------------------------------
1517 if ( ! empty( $is_send_emeils ) ) {
1518 // We are sending emails about the new booking, if we have created it.
1519 // wpbc_send_email_modified( $selected_booking_id, $selected_resource_id, $formdata_new );
1520 }
1521 }
1522 }
1523 }
1524
1525 return array(
1526 'after_action_result' => $after_action_result,
1527 'after_action_message' => $after_action_message
1528 );
1529
1530 }
1531
1532 /**
1533 * Duplicate booking in another resource -- SQL manipulation
1534 * @param $selected_booking_id
1535 * @param $selected_resource_id
1536 *
1537 * @return array
1538 */
1539 function wpbc__sql__duplicate_booking_to_other_resource_for_booking( $selected_booking_id, $selected_resource_id, $params ){
1540 global $wpdb;
1541
1542 $booking_id = intval( $selected_booking_id );
1543 $resource_id = intval( $selected_resource_id );
1544 $db_form_data_new = '';
1545 $booking_resources_arr = wpbc_ajx_get_all_booking_resources_arr();
1546
1547 $is_send_emails = wpbc_ajx__user_request_option__is_send_emails( $params['user_id'] );
1548
1549 ////////////////////////////////////////////////////////////////////////////////////////////////////////////
1550 // 1.Get dates of SOURCE booking
1551 ////////////////////////////////////////////////////////////////////////////////////////////////////////////
1552 if ( 1 ) {
1553 // 1.1.Get booking data of SOURCE booking
1554 $sql = $wpdb->prepare( "SELECT * FROM {$wpdb->prefix}booking as bk WHERE booking_id = %d ", $booking_id );
1555 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.NotPrepared, PluginCheck.Security.DirectDB.UnescapedDBParameter
1556 $res = $wpdb->get_row( $sql );
1557 $db_form_data_old = $res->form;
1558 $resource_id_old = $res->booking_type;
1559
1560 // 1.2. Get dates of SOURCE booking
1561 $sql = $wpdb->prepare( "SELECT * FROM {$wpdb->prefix}bookingdates as dt WHERE booking_id = %d ORDER BY booking_date ASC ", $booking_id );
1562 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.NotPrepared, PluginCheck.Security.DirectDB.UnescapedDBParameter
1563 $old_resource_dates_array = $wpdb->get_results( $sql );
1564 }
1565
1566 ////////////////////////////////////////////////////////////////////////////////////////////////////////////
1567 // 2. Get bookings of selected booking resource - checking if some dates there is booked or not
1568 ////////////////////////////////////////////////////////////////////////////////////////////////////////////
1569 $exist_dates_results = wpbc_get_booking_dates_in_resource_for_folowing_dates( $old_resource_dates_array , $resource_id );
1570
1571 if ( ( count( $exist_dates_results ) == 3 ) && ( false === $exist_dates_results[0] ) ){
1572 // // ERROR :: number of check in/dates does not equal to number of check out dates.
1573 return $exist_dates_results;
1574 }
1575
1576 if ( get_bk_option('booking_change_resource_skip_checking') === 'On' ) { // FixIn: 8.4.5.4.
1577 $is_date_time_booked = false;
1578 } else {
1579 $is_date_time_booked = wpbc_check_dates_intersections( $old_resource_dates_array, $exist_dates_results );
1580 }
1581
1582 if ( $is_date_time_booked ) {
1583
1584 $after_action_result = false;
1585 $after_action_message = '<strong>' . esc_html__( 'Warning', 'booking' ) . '!</strong> '
1586 /* translators: 1: ... */
1587 . sprintf( __( 'Booking %1$s has not been duplicated in booking resource %2$s. Current dates are already booked there.' , 'booking' )
1588 , '<strong style="font-size:0.9em;">[ID=' . $booking_id . ']</strong>'
1589 , '<strong>' . wpbc_lang( $booking_resources_arr[ $resource_id ]['title'] ) . '</strong>'
1590 );
1591
1592 } else { // Possible to change
1593
1594 $db_form_data_new = wpbc_update_resource_id_in_dbformatted_booking_data( $db_form_data_old, $resource_id_old, $resource_id );
1595 // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.MissingUnslash, WordPress.Security.NonceVerification.Recommended
1596 $wpdev_active_locale = isset( $_REQUEST['wpbc_ajx_locale'] ) ? sanitize_text_field( $_REQUEST['wpbc_ajx_locale'] ) : 'en_US';
1597
1598
1599 // Change dates from DateObj( $selected_date->booking_date = '2015-10-17' ) to array ( '17.10.2015' )
1600 $my_dates_for_sql = array();
1601 foreach ($old_resource_dates_array as $selected_date) {
1602 $selected_date = explode( '-', $selected_date->booking_date );
1603 $my_dates_for_sql[] = sprintf( "%02d.%02d.%04d", $selected_date[2], $selected_date[1], $selected_date[0] );
1604 }
1605 $my_dates_for_sql = implode( ', ', $my_dates_for_sql );
1606
1607 // Create a new booking
1608 $request_save_params = array(
1609 'resource_id' => $resource_id, // 2
1610 'dates_ddmmyy_csv' => $my_dates_for_sql, // '04.10.2023, 05.10.2023, 06.10.2023'
1611 'form_data' => $db_form_data_new, // 'text^cost_hint2^150.00฿~selectbox-multiple^rangetime2[]^14:00...'
1612 'booking_hash' => '', // 'sdfsf34534rf'
1613 'custom_form' => '', // 'custom_form_name'
1614 'is_emails_send' => $is_send_emails, // 0 | 1
1615 'is_show_payment_form' => 0 // 0 | 1
1616 // 'request_uri' => $_SERVER['HTTP_REFERER']
1617 // 'user_id' => wpbc_get_current_user_id()
1618 // 'sync_gid' => ''
1619 // 'is_approve_booking' => 0
1620 );
1621 $booking_save_arr = wpbc_booking_save( $request_save_params );
1622
1623 if ( 'ok' === $booking_save_arr['ajx_data']['status'] ) { // Everything Cool :) - booking has been duplicated
1624
1625 $booking_id_new = $booking_save_arr['booking_id'];
1626 $after_action_result = true;
1627 /* translators: 1: ... */
1628 $after_action_message = sprintf( __( 'Booking %1$s has been duplicated in booking resource %2$s. New booking %3$s.', 'booking' )
1629 , '<strong style="font-size:0.9em;">[ID=' . $booking_id . ']</strong>'
1630 , '<strong>' . wpbc_lang( $booking_resources_arr[ $resource_id ]['title'] ) . '</strong>'
1631 , '<strong style="font-size:0.9em;">[ID=' . $booking_id_new . ']</strong>'
1632 );
1633 } else { // Error
1634 $after_action_result = false;
1635 $after_action_message = $booking_save_arr['ajx_data']['ajx_after_action_message'];
1636 }
1637 }
1638
1639 return array( $after_action_result, $after_action_message , $db_form_data_new );
1640 }
1641
1642 /**
1643 * Action: Set payment status for the booking
1644 *
1645 * @param $booking_id_arr array or int of booking ID
1646 * @param $selected_payment_status string payment status of booking
1647 * @param $params array array of parameters: array( 'user_id' => 1 )
1648 *
1649 * @return array
1650 *
1651 * Example:
1652 */
1653 function wpbc_booking_do_action__set_payment_status( $booking_id_arr, $selected_payment_status, $params ) {
1654
1655 global $wpdb;
1656
1657 make_bk_action('check_multiuser_params_for_client_side_by_user_id', $params['user_id'] );
1658
1659 // Get ID list of bookings, like '1' or '3,7,9' ----------------------------------------------------------------
1660 if ( ! is_array( $booking_id_arr ) ) {
1661 $booking_id_arr = array( $booking_id_arr );
1662 }
1663 $booking_id_csd = join( ',', $booking_id_arr );
1664 $booking_id_csd = wpbc_clean_digit_or_csd( $booking_id_csd );
1665
1666
1667 // Is send email for this action ----------------------------------------------------------------------------------
1668 $is_send_emeils = wpbc_ajx__user_request_option__is_send_emails( $params['user_id'] );
1669
1670 // -----------------------------------------------------------------------------------------------------------------
1671
1672 if ( empty( $booking_id_csd ) ) {
1673 $after_action_result = false;
1674 $after_action_message = __( 'No bookings have been selected. Please select one or more bookings.', 'booking' );
1675
1676 } else {
1677 $after_action_result = true;
1678 $after_action_message = '';
1679
1680 $work_booking_id_arr = explode( ',', $booking_id_csd );
1681
1682 foreach ( $work_booking_id_arr as $selected_booking_id ) {
1683
1684 // SQL ---------------------------------------------------------------------------------------------------
1685 $sql = $wpdb->prepare( "SELECT * FROM {$wpdb->prefix}booking as bk WHERE bk.booking_id= %d ", $selected_booking_id );
1686 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.NotPrepared, PluginCheck.Security.DirectDB.UnescapedDBParameter
1687 $result_bk = $wpdb->get_results( $sql );
1688
1689 $old_pay_status = '';
1690
1691 if ( ( 0 == count( $result_bk ) ) ) {
1692 // Error
1693 $after_action_result = false;
1694 /* translators: 1: ... */
1695 $after_action_message .= sprintf( __( 'There is no booking %s', 'booking' )
1696 , ' <span style="font-size:0.9em;">( ID = <strong>' . $booking_id_csd . '</strong> )</span>'
1697 );
1698 } else {
1699 $old_pay_status = $result_bk[0]->pay_status;
1700 }
1701 // FixIn: 10.12.1.5.
1702 $update_sql = $wpdb->prepare( "UPDATE {$wpdb->prefix}booking SET pay_status= %s WHERE booking_id= %d ", $selected_payment_status, $selected_booking_id );
1703 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.NotPrepared, PluginCheck.Security.DirectDB.UnescapedDBParameter
1704 if ( false === $wpdb->query( $update_sql ) ) {
1705 // Error
1706 $after_action_result = false;
1707 $after_action_message .= 'Error during updating to DB. File:' . __FILE__ . ' on line: ' . __LINE__;
1708 } else {
1709 // Success
1710 /* translators: 1: ... */
1711 $after_action_message .= sprintf( __( 'Payment status for Booking %1$s has been updated from %2$s to %3$s', 'booking' )
1712 , ' <span style="font-size:0.9em;">( ID = <strong>' . $selected_booking_id . '</strong> )</span>'
1713 , '<strong>"' . wpbc__format__get_payment_status_title( $old_pay_status ) . '"</strong>'
1714 , '<strong>"' . wpbc__format__get_payment_status_title( $selected_payment_status ) . '"</strong>'
1715 ) . '<br/>';
1716 }
1717
1718
1719 if ( $after_action_result ) {
1720 // LOG ---------------------------------------------------------------------------------------------------------
1721 $curr_user = get_user_by( 'id', (int) $params['user_id'] );
1722 wpbc_db__add_log_info( explode( ',', $selected_booking_id ),
1723 $after_action_message
1724 . '. ' . __( 'Changed by:', 'booking' )
1725 . ' ' . $curr_user->first_name . ' ' . $curr_user->last_name . ' (' . $curr_user->user_email . ')'
1726 );
1727
1728 // Just action hook for some other addons
1729 do_action( 'wpbc_booking_action__set_payment_status', $selected_booking_id, $selected_payment_status , $old_pay_status );
1730
1731 // Emails ------------------------------------------------------------------------------------------------------
1732 if ( ! empty( $is_send_emeils ) ) {
1733 // We are sending emails about the new booking, if we have created it.
1734 // wpbc_send_email_modified( $selected_booking_id, $selected_resource_id, $formdata_new );
1735 }
1736 }
1737 }
1738 }
1739
1740 return array(
1741 'after_action_result' => $after_action_result,
1742 'after_action_message' => $after_action_message
1743 );
1744
1745 }
1746
1747 /**
1748 * Get title of the payment status
1749 *
1750 * @param $payment_status_key
1751 *
1752 * @return string
1753 */
1754 function wpbc__format__get_payment_status_title( $payment_status_key ){
1755
1756 $selected_payment_status_text = $payment_status_key;
1757
1758 $select_box_options = get_payment_status_titles();
1759 $select_box_options = array_flip( $select_box_options );
1760
1761 if ( ! empty( $select_box_options[ $payment_status_key ] ) ) {
1762 $selected_payment_status_text = $select_box_options[ $payment_status_key ];
1763 }
1764
1765 return $selected_payment_status_text;
1766 }
1767
1768
1769 /**
1770 * Action: Set Booking Cost
1771 *
1772 * @param $booking_id_arr array or int of booking ID
1773 * @param $booking_cost string booking cost
1774 * @param $params array array of parameters: array( 'user_id' => 1 )
1775 *
1776 * @return array
1777 *
1778 * Example:
1779 */
1780 function wpbc_booking_do_action__set_booking_cost( $booking_id_arr, $booking_cost, $params ) {
1781
1782 global $wpdb;
1783
1784 make_bk_action('check_multiuser_params_for_client_side_by_user_id', $params['user_id'] );
1785
1786 // Get ID list of bookings, like '1' or '3,7,9' ----------------------------------------------------------------
1787 if ( ! is_array( $booking_id_arr ) ) {
1788 $booking_id_arr = array( $booking_id_arr );
1789 }
1790 $booking_id_csd = join( ',', $booking_id_arr );
1791 $booking_id_csd = wpbc_clean_digit_or_csd( $booking_id_csd );
1792
1793
1794 // Is send email for this action ----------------------------------------------------------------------------------
1795 $is_send_emeils = wpbc_ajx__user_request_option__is_send_emails( $params['user_id'] );
1796
1797 // -----------------------------------------------------------------------------------------------------------------
1798
1799 $booking_cost = str_replace(',', '.', $booking_cost);
1800 $booking_cost = floatval( $booking_cost );
1801
1802
1803 if ( empty( $booking_id_csd ) ) {
1804 $after_action_result = false;
1805 $after_action_message = __( 'No bookings have been selected. Please select one or more bookings.', 'booking' );
1806
1807 } else {
1808 $after_action_result = true;
1809 $after_action_message = '';
1810
1811 $work_booking_id_arr = explode( ',', $booking_id_csd );
1812
1813 foreach ( $work_booking_id_arr as $selected_booking_id ) {
1814
1815 // SQL ---------------------------------------------------------------------------------------------------
1816 $sql = $wpdb->prepare( "SELECT * FROM {$wpdb->prefix}booking as bk WHERE bk.booking_id= %d ", $selected_booking_id );
1817 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.NotPrepared, PluginCheck.Security.DirectDB.UnescapedDBParameter
1818 $result_bk = $wpdb->get_results( $sql );
1819
1820 $old_booking_cost = '';
1821
1822 if ( ( 0 == count( $result_bk ) ) ) {
1823 // Error
1824 $after_action_result = false;
1825 /* translators: 1: ... */
1826 $after_action_message .= sprintf( __( 'There is no booking %s', 'booking' )
1827 , ' <span style="font-size:0.9em;">( ID = <strong>' . $booking_id_csd . '</strong> )</span>'
1828 );
1829 } else {
1830 $old_booking_cost = $result_bk[0]->cost;
1831 }
1832
1833 $update_sql = $wpdb->prepare( "UPDATE {$wpdb->prefix}booking SET cost = %f WHERE booking_id = %d ", $booking_cost, $selected_booking_id ); // FixIn: 10.12.1.5.
1834 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.NotPrepared, PluginCheck.Security.DirectDB.UnescapedDBParameter
1835 if ( false === $wpdb->query( $update_sql ) ) {
1836 // Error
1837 $after_action_result = false;
1838 $after_action_message .= 'Error during updating to DB. File:' . __FILE__ . ' on line: ' . __LINE__;
1839 } else {
1840 // Success
1841 /* translators: 1: ... */
1842 $after_action_message .= sprintf( __( 'Cost for Booking %1$s has been updated from %2$s to %3$s', 'booking' )
1843 , ' <span style="font-size:0.9em;">( ID = <strong>' . $selected_booking_id . '</strong> )</span>'
1844 , '<strong>"' . wpbc__format__get_payment_status_title( $old_booking_cost ) . '"</strong>'
1845 , '<strong>"' . wpbc__format__get_payment_status_title( $booking_cost ) . '"</strong>'
1846 ) . '<br/>';
1847 }
1848
1849
1850 if ( $after_action_result ) {
1851 // LOG ---------------------------------------------------------------------------------------------------------
1852 $curr_user = get_user_by( 'id', (int) $params['user_id'] );
1853 wpbc_db__add_log_info( explode( ',', $selected_booking_id ),
1854 $after_action_message
1855 . '. ' . __( 'Changed by:', 'booking' )
1856 . ' ' . $curr_user->first_name . ' ' . $curr_user->last_name . ' (' . $curr_user->user_email . ')'
1857 );
1858
1859 // Just action hook for some other addons
1860 do_action( 'wpbc_booking_action__set_booking_cost', $selected_booking_id, $booking_cost , $old_booking_cost );
1861
1862 // Emails ------------------------------------------------------------------------------------------------------
1863 if ( ! empty( $is_send_emeils ) ) {
1864
1865 if ( get_bk_option( 'booking_send_email_on_cost_change' ) == 'On' ) { // FixIn: 8.1.3.30.
1866 $booking_data = apply_bk_filter( 'wpbc_get_booking_data', $selected_booking_id );
1867 wpbc_send_email_modified( $selected_booking_id, $booking_data['type'], $booking_data['form'] );
1868 }
1869 }
1870
1871 }
1872 }
1873 }
1874
1875 return array(
1876 'after_action_result' => $after_action_result,
1877 'after_action_message' => $after_action_message
1878 );
1879 }
1880
1881
1882 /**
1883 * Action: Send Payment request
1884 *
1885 * @param $booking_id_arr array or int of booking ID
1886 * @param $booking_cost string booking cost
1887 * @param $params array array of parameters: array( 'user_id' => 1 )
1888 *
1889 * @return array
1890 */
1891 function wpbc_booking_do_action__send_payment_request($booking_id_arr, $reason_of_action, $params ) {
1892 global $wpdb;
1893
1894 make_bk_action('check_multiuser_params_for_client_side_by_user_id', $params['user_id'] );
1895
1896 // Get ID list of bookings, like '1' or '3,7,9' ----------------------------------------------------------------
1897 if ( ! is_array( $booking_id_arr ) ) {
1898 $booking_id_arr = array( $booking_id_arr );
1899 }
1900 $booking_id_csd = join( ',', $booking_id_arr );
1901 $booking_id_csd = wpbc_clean_digit_or_csd( $booking_id_csd );
1902
1903
1904 // Is send email for this action ----------------------------------------------------------------------------------
1905 $is_send_emeils = wpbc_ajx__user_request_option__is_send_emails( $params['user_id'] );
1906
1907 // -----------------------------------------------------------------------------------------------------------------
1908
1909 if ( empty( $booking_id_csd ) ) {
1910 $after_action_result = false;
1911 $after_action_message = __( 'No bookings have been selected. Please select one or more bookings.', 'booking' );
1912
1913 } else {
1914 $after_action_result = true;
1915 $after_action_message = '';
1916
1917 $work_booking_id_arr = explode( ',', $booking_id_csd );
1918
1919 foreach ( $work_booking_id_arr as $selected_booking_id ) {
1920
1921 // SQL ---------------------------------------------------------------------------------------------------
1922 $sql = $wpdb->prepare( "SELECT * FROM {$wpdb->prefix}booking as bk WHERE bk.booking_id= %d ", $selected_booking_id );
1923 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.NotPrepared, PluginCheck.Security.DirectDB.UnescapedDBParameter
1924 $result_bk = $wpdb->get_results( $sql );
1925
1926 $old_booking_cost = '';
1927
1928 if ( ( 0 == count( $result_bk ) ) ) {
1929 // Error
1930 $after_action_result = false;
1931 /* translators: 1: ... */
1932 $after_action_message .= sprintf( __( 'There is no booking %s', 'booking' )
1933 , ' <span style="font-size:0.9em;">( ID = <strong>' . $booking_id_csd . '</strong> )</span>'
1934 );
1935 } else {
1936 $old_booking_cost = $result_bk[0]->cost;
1937
1938 $is_email_payment_request_adress = get_bk_option( 'booking_is_email_payment_request_adress' );
1939 if ( 'Off' != $is_email_payment_request_adress ) {
1940
1941 $reason_of_action = htmlspecialchars( str_replace( '\"', '"', $reason_of_action ) );
1942 $reason_of_action = str_replace( "\'", "'", $reason_of_action );
1943
1944 foreach ( $result_bk as $res ) {
1945
1946 $is_send = wpbc_send_email_payment_request( $res->booking_id, $res->booking_type, $res->form, $reason_of_action );
1947
1948 if ( $is_send ) {
1949 // Update Payment request number
1950 $pay_request_numer = $res->pay_request + 1;
1951 // FixIn: 10.12.1.5.
1952 $update_sql = $wpdb->prepare( "UPDATE {$wpdb->prefix}booking SET pay_request= %d WHERE booking_id= %d ", $pay_request_numer, $res->booking_id );
1953 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.NotPrepared, PluginCheck.Security.DirectDB.UnescapedDBParameter
1954 if ( false === $wpdb->query( $update_sql ) ) {
1955 // Error
1956 $after_action_result = false;
1957 $after_action_message .= 'Error during updating to DB. File:' . __FILE__ . ' on line: ' . __LINE__;
1958 } else {
1959 // Success
1960 /* translators: 1: ... */
1961 $after_action_message .= sprintf( __( 'Payment request for Booking %1$s has been sent. Cost for payment: %2$s', 'booking' )
1962 , ' <span style="font-size:0.9em;">( ID = <strong>' . $selected_booking_id . '</strong> )</span>'
1963 , '<strong>"' . wpbc__format__get_payment_status_title( $old_booking_cost ) . '"</strong>'
1964 ) . '<br/>';
1965 }
1966 }
1967 }
1968 }
1969 }
1970
1971 if ( $after_action_result ) {
1972 // LOG ---------------------------------------------------------------------------------------------------------
1973 $curr_user = get_user_by( 'id', (int) $params['user_id'] );
1974 wpbc_db__add_log_info( explode( ',', $selected_booking_id ),
1975 $after_action_message
1976 . '. ' . __( 'Send by:', 'booking' )
1977 . ' ' . $curr_user->first_name . ' ' . $curr_user->last_name . ' (' . $curr_user->user_email . ')'
1978 );
1979
1980 // Just action hook for some other addons
1981 do_action( 'wpbc_booking_action__send_payment_request', $selected_booking_id, $reason_of_action , $old_booking_cost );
1982
1983 // Emails ------------------------------------------------------------------------------------------------------
1984 /*
1985 if ( ! empty( $is_send_emeils ) ) {
1986
1987 if ( get_bk_option( 'booking_send_email_on_cost_change' ) == 'On' ) {
1988 $booking_data = apply_bk_filter( 'wpbc_get_booking_data', $selected_booking_id );
1989 wpbc_send_email_modified( $selected_booking_id, $booking_data['type'], $booking_data['form'] );
1990 }
1991 }
1992 */
1993 }
1994 }
1995
1996 }
1997
1998 return array(
1999 'after_action_result' => $after_action_result,
2000 'after_action_message' => $after_action_message
2001 );
2002 }
2003
2004
2005 function wpbc_booking_do_action__import_google_calendar( $request_params, $params ) {
2006
2007 $return_array = array();
2008
2009 $user_bk_id = (int) $params['user_id'];
2010
2011 global $wpdb;
2012
2013 $wpbc_Google_Calendar = new WPBC_Google_Calendar();
2014
2015 $wpbc_Google_Calendar->setSilent();
2016
2017 $wpbc_Google_Calendar->set_timezone( get_bk_option('booking_gcal_timezone') );
2018
2019 $wpbc_Google_Calendar->set_events_from_with_array( array(
2020 $request_params['booking_gcal_events_from'],
2021 $request_params['booking_gcal_events_from_offset'],
2022 $request_params['booking_gcal_events_from_offset_type']
2023 ) );
2024
2025 $wpbc_Google_Calendar->set_events_until_with_array( array(
2026 $request_params['booking_gcal_events_until'],
2027 $request_params['booking_gcal_events_until_offset'],
2028 $request_params['booking_gcal_events_until_offset_type']
2029 ) );
2030
2031 $wpbc_Google_Calendar->set_events_max( $request_params['booking_gcal_events_max'] );
2032
2033 if ( ( isset( $request_params['booking_gcal_resource'] ) ) && ( empty( $request_params['booking_gcal_resource'] ) ) ) {
2034
2035 $wpbc_Google_Calendar->setUrl( get_bk_option( 'booking_gcal_feed') );
2036 $import_result = $wpbc_Google_Calendar->run();
2037
2038 } else {
2039
2040 if ( $request_params['booking_gcal_resource'] != 'all' ) { // One resource
2041
2042 $wpbc_booking_resource_id = intval( $request_params['booking_gcal_resource'] );
2043
2044 $wpbc_Google_Calendar->setResource( $wpbc_booking_resource_id );
2045
2046 $wpbc_booking_resource_feed = get_booking_resource_attr( $wpbc_booking_resource_id );
2047 $wpbc_booking_resource_feed = $wpbc_booking_resource_feed->import;
2048 $wpbc_Google_Calendar->setUrl( $wpbc_booking_resource_feed );
2049
2050 $import_result = $wpbc_Google_Calendar->run();
2051 } else { // All resources
2052
2053 $where = ''; // Where for the different situation: BL and MU
2054
2055 if ( class_exists( 'wpdev_bk_multiuser' ) ) { // MultiUser - only specific booking resources for specific Regular User in Admin panel.
2056
2057 $is_user_super_admin = apply_bk_filter( 'is_user_super_admin', $user_bk_id );
2058
2059 if ( ! $is_user_super_admin ) {
2060 $where .= ' WHERE users = ' . intval( $user_bk_id ) . ' ';
2061 }
2062 }
2063
2064 $my_sql = "SELECT booking_type_id, import FROM {$wpdb->prefix}bookingtypes {$where}";
2065 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.NotPrepared, PluginCheck.Security.DirectDB.UnescapedDBParameter
2066 $types_list = $wpdb->get_results( $my_sql );
2067
2068 foreach ($types_list as $wpbc_booking_resource) {
2069 $wpbc_booking_resource_id = $wpbc_booking_resource->booking_type_id;
2070 $wpbc_booking_resource_feed = $wpbc_booking_resource->import;
2071 if ( ( ! empty( $wpbc_booking_resource_feed ) ) && ( $wpbc_booking_resource_feed != null ) && ( $wpbc_booking_resource_feed != '/' ) ) {
2072
2073 $wpbc_Google_Calendar->setUrl( $wpbc_booking_resource_feed );
2074 $wpbc_Google_Calendar->setResource( $wpbc_booking_resource_id );
2075 $import_result = $wpbc_Google_Calendar->run();
2076 }
2077 }
2078 }
2079 }
2080
2081
2082 if ( ( isset( $import_result ) ) && ( false != $import_result ) ) {
2083 $after_action_result = true;
2084 /* translators: 1: ... */
2085 $after_action_message = sprintf( __( '%s new bookings have been imported', 'booking' )
2086 , ' <span style="font-size:1em;"> <strong>' . count( $wpbc_Google_Calendar->events ) . '</strong> </span>'
2087 ) ;
2088 if ( 0 != count( $wpbc_Google_Calendar->events ) ) {
2089 $after_action_message .= '<br/><br/>' . esc_html__( 'The filter settings have been updated to reflect these imported bookings. The page will be reloaded.', 'booking' );
2090 }
2091
2092 if ( ! empty( $wpbc_Google_Calendar->getErrorMessage() ) ) {
2093 $after_action_message .= '<div style="max-width:60rem;margin:2em 10px;">' . $wpbc_Google_Calendar->getErrorMessage() . '</div>';
2094 $return_array['after_action_result_delay'] = 100000000000000;
2095 }
2096
2097 } else {
2098 $after_action_result = false;
2099 $after_action_message = __( 'No bookings have been imported.', 'booking' )
2100 . '<br/><br/>'
2101 . sprintf( __( 'Please configure settings for import Google Calendar events', 'booking' ), '<b>', ',</b>' )
2102 . ' <a href="' . esc_url( wpbc_get_settings_url() . '&tab=sync&subtab=gcal' ). '">' . esc_html__('here' ,'booking') . '.</a>'
2103 . '<br/><br/>'
2104 . $wpbc_Google_Calendar->getErrorMessage();
2105 $return_array['after_action_result_delay'] = 100000000000000;
2106 }
2107
2108
2109 if ( 0 == count( $wpbc_Google_Calendar->events ) ) {
2110 $new_listing_params = false;
2111 } else {
2112 $new_listing_params = array(
2113 "sort" => "booking_id",
2114 "sort_type" => "DESC",
2115 "page_num" => 1,
2116 "page_items_count" => "50",
2117 "create_date" => "",
2118 "keyword" => "",
2119 "source" => "",
2120 "wh_booking_type" => array( "0" ),
2121 "wh_approved" => "",
2122 "wh_booking_date" => array( "3" ),
2123 "ui_wh_booking_date_radio" => 0,
2124 "ui_wh_booking_date_next" => 1,
2125 "ui_wh_booking_date_prior" => 1,
2126 "ui_wh_booking_date_checkin" => "",
2127 "ui_wh_booking_date_checkout" => "",
2128 "wh_what_bookings" => "imported",
2129 "wh_modification_date" => array( "1" ),
2130 "ui_wh_modification_date_prior" => "1",
2131 "ui_wh_modification_date_checkin" => "",
2132 "ui_wh_modification_date_checkout" => "",
2133 "wh_pay_status" => array( "all" ),
2134 "ui_wh_pay_status_radio" => "",
2135 "ui_wh_pay_status_custom" => "",
2136 "wh_cost" => "",
2137 "wh_cost2" => "",
2138 "wh_sort" => "booking_id__desc",
2139 "wh_trash" => "any",
2140 'reload_url_params' => htmlspecialchars_decode( esc_url( wpbc_get_bookings_url() . '&tab=vm_booking_listing' ) )
2141 );
2142 }
2143
2144
2145 $return_array['after_action_result'] = $after_action_result;
2146 $return_array['after_action_message'] = $after_action_message;
2147 $return_array['new_listing_params'] = $new_listing_params;
2148
2149 return $return_array;
2150 }
2151
2152
2153 function wpbc_booking_do_action__export_csv( $request_params, $params ){
2154
2155 global $wpdb;
2156
2157 make_bk_action( 'check_multiuser_params_for_client_side_by_user_id', $params['user_id'] );
2158
2159 $booking_id_csd = $request_params['booking_id'];
2160 $booking_id_csd = wpbc_clean_digit_or_csd( $booking_id_csd );
2161 if ( empty( $booking_id_csd ) ) {
2162 // Export all bookings (no selected bookings was in the listing
2163 }
2164
2165 $export_type = $request_params['export_type']; // csv_page | csv_all
2166
2167 // Is send email for this action ----------------------------------------------------------------------------------
2168 $is_send_emeils = wpbc_ajx__user_request_option__is_send_emails( $params['user_id'] );
2169
2170 // -----------------------------------------------------------------------------------------------------------------
2171
2172 // phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.NonceVerification.Missing
2173 if ( ! isset( $_POST['search_params'] ) || empty( $_POST['search_params'] ) ) {
2174
2175 $after_action_result = false;
2176 $after_action_message = __('Error', 'booking') . '! ' . 'Search parameters for CSV generating are empty.';
2177
2178 } else {
2179
2180
2181 $user_request = new WPBC_AJX__REQUEST( array(
2182 'db_option_name' => 'booking_listing_request_params',
2183 'user_id' => wpbc_get_current_user_id(),
2184 'request_rules_structure' => wpbc_ajx_get__request_params__names_default()
2185 )
2186 );
2187 $request_prefix = 'search_params';
2188 $request_params_for_listing = $user_request->get_sanitized__in_request__value_or_default( $request_prefix ); // NOT Direct: $_REQUEST['search_params']['resource_id']
2189
2190
2191
2192 // $data_arr = wpbc_ajx_get_booking_data_arr( $request_params_for_listing );
2193
2194 $export_csv_url = wpbc_csv_get_url_export( $request_params_for_listing );
2195
2196 $after_action_result = true;
2197 $after_action_message = __('Processing' ,'booking') . '... ';
2198 }
2199
2200 // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.MissingUnslash, WordPress.Security.NonceVerification.Recommended
2201 $wpbc_ajx_locale = ( isset( $_REQUEST['wpbc_ajx_locale'] ) ) ? sanitize_text_field( $_REQUEST['wpbc_ajx_locale'] ) : 'en_US';
2202
2203 return array(
2204
2205 'export_csv_url' => $export_csv_url
2206 . '&export_type=' . $export_type
2207 . '&selected_id=' . $booking_id_csd
2208 . '&csv_export_separator=' . $request_params['csv_export_separator']
2209 . '&csv_export_skip_fields=' . $request_params['csv_export_skip_fields']
2210 . '&wpbc_ajx_locale=' . $wpbc_ajx_locale
2211 . '&wpbc_ajx_locale_reload=force' ,
2212 'after_action_result' => $after_action_result,
2213 'after_action_message' => $after_action_message
2214 );
2215 }
2216 // </editor-fold>
2217
2218
2219 // <editor-fold defaultstate="collapsed" desc=" == Button Actions Templates for UI == " >
2220
2221 /**
2222 * Show Read booking Button
2223 */
2224 function wpbc_for_booking_template__action_read(){
2225
2226 $booking_action = 'set_booking_as_read';
2227
2228 if ( ! wpbc_is_user_can( $booking_action, wpbc_get_current_user_id() ) ) {
2229 return false;
2230 }
2231
2232 $params = array(
2233 'type' => 'button',
2234 'title' => '',
2235 'hint' => array(
2236 'title' => __( 'New booking', 'booking' ),
2237 'position' => 'top'
2238 ),
2239 'link' => 'javascript:void(0)',
2240 'action' => " wpbc_ajx_booking_ajax_action_request( {
2241 'booking_action' : '{$booking_action}',
2242 'booking_id' : {{data['parsed_fields']['booking_id']}}
2243 } );
2244 wpbc_button_enable_loading_icon( this ); ",
2245 'icon' => array(
2246 'icon_font' => 'wpbc_icn_fiber_manual_record',// 'wpbc_icn_visibility',
2247 'position' => 'left',
2248 'icon_img' => ''
2249 ),
2250 'class' => 'wpbc_is_new_button',
2251 'style' => '',
2252 'mobile_show_text' => true,
2253 'attr' => array()
2254 );
2255
2256 ?><# if ( '1' == data.parsed_fields.is_new ) { #><?php
2257 wpbc_flex_button( $params );
2258 ?><# } #><?php
2259 }
2260
2261 // </editor-fold>
2262
2263
2264
2265 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2266 // Support functions
2267 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2268
2269 /**
2270 * Catch some errors, if such errors exist during our Ajx request
2271 */
2272 class WPBC_AJAX_ERROR_CATCHING{
2273
2274 public $errors_arr;
2275
2276 function __construct() {
2277
2278 $this->errors_arr = array();
2279
2280 // Catch Error messages
2281 add_action( 'wp_error_added', array( $this, 'wpbc_wp_error_added' ), 10, 4 );
2282
2283 if ( ! defined( 'WPBC_AJAX_ERROR_CATCH' ) ) { define( 'WPBC_AJAX_ERROR_CATCH', true ); } // Check somewhere to not show error messages: if ( ( defined( 'WPBC_AJAX_ERROR_CATCH' ) ) && ( WPBC_AJAX_ERROR_CATCH ) ) { return false; }
2284 }
2285
2286 /**
2287 * Catch Error messages
2288 *
2289 * @param $code
2290 * @param $message
2291 * @param $data
2292 * @param $this_link
2293 *
2294 * @return void
2295 */
2296 function wpbc_wp_error_added( $code, $message, $data, $this_link ){
2297
2298 $this->errors_arr[] = array(
2299 'code' => $code,
2300 'message' => $message,
2301 'data' => $data,
2302 'this_link' => $this_link
2303 ) ;
2304 }
2305
2306 /**
2307 * Get summary of all errors
2308 * @return string
2309 */
2310 function get_error_messages(){
2311
2312 $error_message = array();
2313
2314 foreach ( $this->errors_arr as $error ) {
2315 $error_message[] = 'Error: ' . $error['code'] . '. ' . $error['message'];
2316 }
2317 $error_message = implode( '<br/>', $error_message );
2318
2319 if ( ! empty( $error_message ) ) {
2320 $error_message = '<div class="wpbc_ajx_errors">'
2321 .'<br/><strong>' . esc_html__( 'Some errors were encountered.', 'booking' ) . '</strong><br/>'
2322 . $error_message
2323 . '</div>';
2324 }
2325 return $error_message;
2326 }
2327 }
2328
2329
2330 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2331 // Check what user can do
2332 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2333
2334 /**
2335 * Check permission of this user on specific actions, like approving or deleting of bookings
2336 *
2337 * @param string $action like 'set_pnding'
2338 * @param int $user_id like 1
2339 *
2340 * @return bool
2341 */
2342 function wpbc_is_user_can( $action, $user_id = 0 ){
2343
2344 if ( 0 == $user_id ) {
2345 $user_id = wpbc_get_current_user_id();
2346 }
2347 $user = get_userdata( $user_id );
2348 $user_roles = (array) ( empty( $user ) ? array() : $user->roles ); // Standard WordPress Roles: 'administrator' | 'editor' | 'author' | 'contributor' | 'subscriber'
2349
2350
2351 // Get here list of actions that user can do
2352 switch ( $action ) {
2353 case 'set_booking_pending':
2354 break;
2355 case 'set_booking_approved':
2356 break;
2357 case 'move_booking_to_trash':
2358 break;
2359 case 'restore_booking_from_trash':
2360 break;
2361 case 'delete_booking_completely':
2362 // if ( ! in_array( 'administrator', $user_roles ) ) { return false; }
2363 break;
2364 case 'booking_add_google_calendar':
2365 break;
2366 case 'set_booking_locale':
2367 break;
2368 case 'set_booking_as_read':
2369 break;
2370 case 'set_booking_as_unread':
2371 break;
2372 case 'empty_trash':
2373 break;
2374 case 'set_booking_note':
2375 break;
2376 case 'edit_booking':
2377 break;
2378 case 'change_booking_resource':
2379 break;
2380 case 'duplicate_booking_to_other_resource':
2381 break;
2382 case 'set_payment_status':
2383 break;
2384 case 'set_booking_cost':
2385 break;
2386 case 'send_payment_request':
2387 break;
2388 case 'import_google_calendar':
2389 break;
2390 case 'export_csv':
2391 break;
2392 default:
2393 // Default
2394 }
2395
2396 return true;
2397 }