PluginProbe
Booking Calendar / 10.10
Booking Calendar v10.10
11.8.2 11.8.1 11.8 11.7 11.6.1 11.6 11.5 11.4.3 11.4.2 11.4.1 11.4 11.3 11.2.1 11.2 11.1 11.0 10.15.7 10.15.6 10.1.3 10.10 10.10.1 10.10.2 10.11 10.11.2 10.11.3 All 202 releases
booking / core / wpbc_functions.php

wpbc_functions.php in Booking Calendar 10.10, at core/wpbc_functions.php

1,607 lines 54.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * @version 1.0
4 * @package Booking Calendar
5 * @subpackage Support Functions
6 * @category Functions
7 *
8 * @author wpdevelop
9 * @link https://wpbookingcalendar.com/
10 * @email info@wpbookingcalendar.com
11 *
12 * @modified 29.09.2015
13 */
14
15 if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
16
17 // <editor-fold defaultstate="collapsed" desc=" == Get html preview of shortcode for Edit pages == " >
18
19 /**
20 * Get html preview of shortcode for Edit pages in Elementor and at Block editors
21 *
22 * @param $shortcode_type
23 * @param $attr
24 *
25 * @return string
26 */
27 function wpbc_get_preview_for_shortcode( $shortcode_type, $attr ) {
28
29 // FixIn: 9.9.0.39.
30
31 return '<div style="border:2px dashed #ccc;text-align: center; padding:10px;display:flex;flex-flow:column wrap;justify-content: center;align-content: center;">
32 <div>WP Booking Calendar Shortcode</div>
33 <code>['.$shortcode_type.' ...]</code>
34 <div style="font-size:0.8em;">This is not a real preview. Publish the page to see it in action.</div>
35 </div>';
36 }
37 // </editor-fold>
38
39
40 // <editor-fold defaultstate="collapsed" desc=" == Calendar functions == " >
41
42 /**
43 * Get maximum visible days in calendar
44 *
45 * @return int
46 */
47 function wpbc_get_max_visible_days_in_calendar(){
48
49 // Number of months to scroll
50 $max_visible_days_in_calendar = get_bk_option( 'booking_max_monthes_in_calendar');
51
52 if ( false !== strpos( $max_visible_days_in_calendar, 'm' ) ) {
53 //$max_visible_days_in_calendar = intval( str_replace( 'm', '', $max_visible_days_in_calendar ) ) * 31 ; // FixIn: 9.6.1.1.
54 // FixIn: 10.0.0.26.
55 $diff_days = strtotime( '+' . intval( str_replace( 'm', '', $max_visible_days_in_calendar ) ) . ' months', strtotime( 'now' ) ) - strtotime( 'now' );
56 $max_visible_days_in_calendar = round( $diff_days / ( 60 * 60 * 24 ) ) + 1;
57 } else {
58 $max_visible_days_in_calendar = intval( str_replace( 'y', '', $max_visible_days_in_calendar ) ) * 365 + 15; // FixIn: 9.6.1.1.
59 }
60
61 return $max_visible_days_in_calendar;
62 }
63
64
65 /**
66 * Parse {calendar ....} option parameter in Calendar | Booking form shortcode
67 *
68 * @param $bk_options
69 *
70 * @return array|false
71 */
72 function wpbc_parse_calendar_options( $bk_options ) {
73
74 if ( empty( $bk_options ) ) {
75 return false;
76 }
77 /* $matches structure:
78 * Array
79 (
80 [0] => Array
81 (
82 [0] => {calendar months="6" months_num_in_row="2" width="341px" cell_height="48px"},
83 [1] => calendar
84 [2] => months="6" months_num_in_row="2" width="341px" cell_height="48px"
85 )
86
87 [1] => Array
88 (
89 [0] => {select-day condition="weekday" for="5" value="3"},
90 [1] => select-day
91 [2] => condition="weekday" for="5" value="3"
92 )
93 .....
94 )
95 */
96
97 $pattern_to_search='%\s*{([^\s]+)\s*([^}]+)\s*}\s*[,]?\s*%';
98
99 preg_match_all( $pattern_to_search, $bk_options, $matches, PREG_SET_ORDER );
100
101 foreach ( $matches as $value ) {
102 if ( $value[1] == 'calendar' ) {
103 $paramas = $value[2];
104 $paramas = trim( $paramas );
105 $paramas = explode( ' ', $paramas );
106 $options = array();
107 foreach ( $paramas as $vv ) {
108 if ( ! empty( $vv ) ) {
109 $vv = trim( $vv );
110 $vv = explode( '=', $vv );
111 if ( ( isset( $vv[0] ) ) && ( isset( $vv[1] ) ) ) {
112 $options[ $vv[0] ] = trim( $vv[1] );
113 }
114 }
115 }
116 if ( count( $options ) == 0 ) {
117 return false;
118 } else {
119 return $options;
120 }
121 }
122 }
123
124 return false; // We are not have the "calendar" options in the shortcode
125 }
126
127
128
129 /**
130 * Parse {calendar ....} option parameter in Calendar | Booking form shortcode
131 *
132 * @param $bk_options
133 *
134 * @return array|false
135 */
136 function wpbc_parse_calendar_options__aggregate_param( $bk_options ) { // FixIn: 9.8.15.10.
137
138 if ( empty( $bk_options ) ) {
139 return false;
140 }
141 /* $matches structure:
142 $matches = [
143 0 = [
144 0 = "{aggregate type=bookings_only}"
145 1 = "aggregate"
146 2 = "type=bookings_only"
147 ]
148 ]
149 */
150
151 $pattern_to_search='%\s*{([^\s]+)\s*([^}]+)\s*}\s*[,]?\s*%';
152
153 preg_match_all( $pattern_to_search, $bk_options, $matches, PREG_SET_ORDER );
154
155 foreach ( $matches as $value ) {
156 if ( $value[1] == 'aggregate' ) {
157 $paramas = $value[2];
158 $paramas = trim( $paramas );
159 $paramas = explode( ' ', $paramas );
160 $options = array();
161 foreach ( $paramas as $vv ) {
162 if ( ! empty( $vv ) ) {
163 $vv = trim( $vv );
164 $vv = explode( '=', $vv );
165 if ( ( isset( $vv[0] ) ) && ( isset( $vv[1] ) ) ) {
166 $options[ $vv[0] ] = trim( $vv[1] );
167 }
168 }
169 }
170 if ( count( $options ) == 0 ) {
171 return false;
172 } else {
173 return $options;
174 }
175 }
176 }
177
178 return false; // We are not have the "calendar" options in the shortcode
179 }
180
181
182 function wpbc_is_calendar_skin_legacy( $skin_name ){
183 $legacy_skins = array(
184 'black.css',
185 'multidays.css',
186 'premium-black.css',
187 'premium-light-noborder.css',
188 'premium-light.css',
189 'premium-marine.css',
190 'premium-steel-noborder.css',
191 'premium-steel.css',
192 'standard.css',
193 'traditional-light.css',
194 'traditional.css'
195 // FixIn: 10.7.1.5.
196 , 'traditional-times.css'
197 , 'black-2.css'
198 , 'green-01.css'
199 , 'light-01.css'
200 );
201
202 return in_array( $skin_name, $legacy_skins );
203 }
204
205
206 /**
207 * Get Legacy calendar skin
208 *
209 * @param $skin_name = 'Black-2'
210 * @param $skin_arr = ["24_9__dark_1.css", "/css/skins/blac...", "Black-2"]
211 *
212 * @return mixed
213 */
214 function wpbc_get_legacy_calendar_skin_name($skin_name, $skin_arr){
215
216 if (wpbc_is_calendar_skin_legacy($skin_arr[0]) ){
217 return __( 'Legacy', 'booking' ) . ': ' . $skin_name;
218 } else {
219 return $skin_name;
220 }
221 }
222
223 /**
224 * Get Calendar skin options for selectboxes
225 * @return void
226 */
227 function wpbc_get_calendar_skin_options( $url_prefix = '' ){
228 // Calendar Skin /////////////////////////////////////////////////////
229 $calendar_skins_options = array();
230 $legacy_calendar_skins_options = array();
231 // Skins in the Custom User folder (need to create it manually): http://example.com/wp-content/uploads/wpbc_skins/ ( This folder do not owerwrited during update of plugin )
232 $upload_dir = wp_upload_dir();
233 // FixIn: 8.9.4.8.
234 $files_in_folder = wpbc_dir_list( array( WPBC_PLUGIN_DIR . '/css/skins/' ) ); // Folders where to look about calendar skins
235 foreach ( $files_in_folder as $skin_file ) { // Example: $skin_file['/css/skins/standard.css'] => 'Standard';
236
237 //FixIn: 8.9.4.8 // FixIn: 9.1.2.10.
238 $skin_file[1] = str_replace( array( WPBC_PLUGIN_DIR, WPBC_PLUGIN_URL , $upload_dir['basedir'] ), '', $skin_file[1] ); // Get relative path for calendar skin
239
240 if ( ! wpbc_is_calendar_skin_legacy( $skin_file[0] ) ) {
241 $calendar_skins_options[ $skin_file[1] ] = $skin_file[2];
242 } else {
243 $legacy_calendar_skins_options[ $skin_file[1] ] = wpbc_get_legacy_calendar_skin_name( $skin_file[2], $skin_file );
244 }
245 }
246
247 $calendar_skins_options_real = array();
248 $calendar_skins_options_real[] = array( 'optgroup' => true, 'close' => false, 'title' => '&nbsp;' . __('Calendar Skins' ,'booking') );
249 foreach ( $calendar_skins_options as $s_key => $s_val ) {
250 $calendar_skins_options_real [ $url_prefix . $s_key ] = $s_val;
251 }
252 $calendar_skins_options_real[] = array( 'optgroup' => true, 'close' => true );
253 $calendar_skins_options_real[] = array( 'optgroup' => true, 'close' => false, 'title' => '&nbsp;' . __('Legacy Calendar Skins' ,'booking') );
254 foreach ( $legacy_calendar_skins_options as $s_key => $s_val ) {
255 $calendar_skins_options_real [ $url_prefix . $s_key ] = array( 'title' => $s_val, 'attr' => array( 'style' => 'color:#ccc;' ) );
256 }
257 $calendar_skins_options_real[] = array( 'optgroup' => true, 'close' => true );
258 $calendar_skins_options_real[] = array( 'optgroup' => true, 'close' => false, 'title' => '&nbsp;' . __('Custom Calendar Skins' ,'booking') );
259 $files_in_folder = wpbc_dir_list( array( $upload_dir['basedir'].'/wpbc_skins/' ) ); // Folders where to look about calendar skins
260 foreach ( $files_in_folder as $skin_file ) { // Example: $skin_file['/css/skins/standard.css'] => 'Standard';
261
262 //FixIn: 8.9.4.8 // FixIn: 9.1.2.10.
263 $skin_file[1] = str_replace( array( WPBC_PLUGIN_DIR, WPBC_PLUGIN_URL , $upload_dir['basedir'] ), '', $skin_file[1] ); // Get relative path for calendar skin
264
265 $calendar_skins_options_real[ $url_prefix . $skin_file[1] ] = $skin_file[2];
266
267 }
268
269 $calendar_skins_options_real[] = array( 'optgroup' => true, 'close' => true );
270
271 return $calendar_skins_options_real;
272 }
273 // </editor-fold>
274
275
276 // <editor-fold defaultstate="collapsed" desc=" == Files functions == " >
277
278 // Get array of images - icons inside of this directory
279 function wpbc_dir_list ($directories) {
280
281 // create an array to hold directory list
282 $results = array();
283
284 if (is_string($directories)) $directories = array($directories);
285 foreach ($directories as $dir) {
286 if ( is_dir( $dir ) ) {
287 $directory = $dir;
288 } else {
289 $directory = WPBC_PLUGIN_DIR . $dir;
290 }
291
292 if ( file_exists( $directory ) ) { //FixIn: 5.4.5
293 // create a handler for the directory
294 $handler = @opendir($directory);
295 if ($handler !== false) {
296 // keep going until all files in directory have been read
297 while ($file = readdir($handler)) {
298
299 // if $file isn't this directory or its parent,
300 // add it to the results array
301 if ($file != '.' && $file != '..' && ( strpos($file, '.css' ) !== false ) )
302 $results[] = array($file, /* WPBC_PLUGIN_URL .*/ $dir . $file, ucfirst(strtolower( str_replace('.css', '', $file))) );
303 }
304
305 // tidy up: close the handler
306 closedir($handler);
307 }
308 }
309 }
310 // done!
311 return $results;
312 }
313
314
315 /**
316 * Check if such file exist or not.
317 *
318 * @param string $path - relative path to file (relative to plugin folder).
319 * @return boolean true | false
320 */
321 function wpbc_is_file_exist( $path ) {
322
323 if ( file_exists( trailingslashit( WPBC_PLUGIN_DIR ) . ltrim( $path, '/\\' ) ) ) // check if this file exist
324 return true;
325 else
326 return false;
327 }
328
329
330 /**
331 * Count the number of bytes of a given string.
332 * Input string is expected to be ASCII or UTF-8 encoded.
333 * Warning: the function doesn't return the number of chars
334 * in the string, but the number of bytes.
335 * See http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
336 * for information on UTF-8.
337 *
338 * @param string $str The string to compute number of bytes
339 *
340 * @return The length in bytes of the given string.
341 */
342 function wpbc_get_bytes_from_str( $str ) {
343 // STRINGS ARE EXPECTED TO BE IN ASCII OR UTF-8 FORMAT
344 // Number of characters in string
345 $strlen_var = strlen( $str );
346
347 $d = 0; // string bytes counter
348
349 // Iterate over every character in the string, escaping with a slash or encoding to UTF-8 where necessary
350 for ( $c = 0; $c < $strlen_var; ++ $c ) {
351 $ord_var_c = ord( $str[$c] ); // FixIn: 2.0.17.1.
352 switch ( true ) {
353 case(($ord_var_c >= 0x20) && ($ord_var_c <= 0x7F)): // characters U-00000000 - U-0000007F (same as ASCII)
354 $d ++;
355 break;
356 case(($ord_var_c & 0xE0) == 0xC0): // characters U-00000080 - U-000007FF, mask 110XXXXX
357 $d += 2;
358 break;
359 case(($ord_var_c & 0xF0) == 0xE0): // characters U-00000800 - U-0000FFFF, mask 1110XXXX
360 $d += 3;
361 break;
362 case(($ord_var_c & 0xF8) == 0xF0): // characters U-00010000 - U-001FFFFF, mask 11110XXX
363 $d += 4;
364 break;
365 case(($ord_var_c & 0xFC) == 0xF8): // characters U-00200000 - U-03FFFFFF, mask 111110XX
366 $d += 5;
367 break;
368 case(($ord_var_c & 0xFE) == 0xFC): // characters U-04000000 - U-7FFFFFFF, mask 1111110X
369 $d += 6;
370 break;
371 default:
372 $d ++;
373 }
374 }
375 return $d;
376 }
377
378
379 // </editor-fold>
380
381
382 // <editor-fold defaultstate="collapsed" desc=" == Can I Load JavaScript Files == " >
383
384 function wpbc_can_i_load_on__edit_new_post_page() {
385
386 if ( ! current_user_can( 'edit_posts' ) && ! current_user_can( 'edit_pages' ) ) {
387 return false;
388 }
389
390
391 $pages_where_load = array( 'post-new.php', 'page-new.php', 'post.php', 'page.php', 'widgets.php', 'customize.php' );
392 // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotValidated
393 if ( ( in_array( basename( $_SERVER['PHP_SELF'] ), $pages_where_load ) )
394 || ( wpbc_is_setup_wizard_page() )
395 ) {
396 return true;
397 }
398
399 return false;
400 }
401
402
403 function wpbc_can_i_load_on__searchable_resources_page() {
404
405 if (
406 ( isset( $_REQUEST['page'] ) ) && ( $_REQUEST['page'] === 'wpbc-resources' ) // phpcs:ignore WordPress.Security.NonceVerification.Recommended
407 && ( isset( $_REQUEST['tab'] ) ) && ( $_REQUEST['tab'] === 'searchable_resources' ) // phpcs:ignore WordPress.Security.NonceVerification.Recommended
408 ) {
409 return true;
410 }
411
412 return false;
413 }
414
415
416 function wpbc_can_i_load_on__resources_page() {
417
418 if (
419 ( isset( $_REQUEST['page'] ) ) && ( $_REQUEST['page'] === 'wpbc-resources' ) // phpcs:ignore WordPress.Security.NonceVerification.Recommended
420 ) {
421 return true;
422 }
423
424 return false;
425 }
426
427
428 /**
429 * Can I load scripts on this page for 'shortcode_config'
430 *
431 * @return bool
432 */
433 function wpbc_can_i_load_on_this_page__shortcode_config() {
434
435 if (
436 wpbc_can_i_load_on__edit_new_post_page()
437 || (
438 wpbc_can_i_load_on__resources_page()
439 && ( ! wpbc_can_i_load_on__searchable_resources_page() )
440 )
441 || wpbc_is_setup_wizard_page()
442 // || wpbc_is_bookings_page() // FixIn: 10.6.6.2.
443 ){
444 return true;
445 } else {
446 return false;
447 }
448 }
449
450 /**
451 * Can I load scripts on this page? Loaded only at ../admin.php?page=wpbc-resources&tab=searchable_resources
452 *
453 * @return bool
454 */
455 function wpbc_can_i_load_on_this_page__modal_search_options() {
456
457 if ( wpbc_can_i_load_on__searchable_resources_page() ){
458 return true;
459 } else {
460 return false;
461 }
462 }
463
464 // </editor-fold>
465
466
467 // <editor-fold defaultstate="collapsed" desc=" == Footer == " >
468
469 function wpbc_show_booking_footer(){
470
471 $wpdev_copyright_adminpanel = get_bk_option( 'booking_wpdev_copyright_adminpanel' ); // check
472
473 $message = '';
474
475
476
477 if ( ( 'Off' !== $wpdev_copyright_adminpanel ) && ( ! wpbc_is_this_demo() ) ) {
478
479
480 /* translators: 1: ... */
481 $message .= sprintf( __( 'If you like %1$s please leave us a %2$s rating. A huge thank you in advance!', 'booking' )
482 , '<strong>Booking Calendar</strong> ' . esc_attr( WP_BK_VERSION_NUM )
483 , '<a href="https://wordpress.org/support/plugin/booking/reviews/#new-post" target="_blank" title="' . esc_attr__( 'Thanks :)', 'booking' ) . '">'
484 . '&#9733;&#9733;&#9733;&#9733;&#9733;'
485 . '</a>'
486 );
487 }
488
489
490 if ( ! empty( $message ) ) {
491
492 // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
493 echo '<div id="wpbc-footer" style="position:absolute;bottom:40px;text-align:left;width:95%;font-size:0.9em;text-shadow:0 1px 0 #fff;margin:0;color:#888;">' . $message . '</div>';
494
495 ?>
496 <script type="text/javascript">
497 jQuery(document).ready(function () {
498 jQuery('#wpfooter').append(jQuery('#wpbc-footer'));
499 });
500 </script>
501 <?php
502 }
503 }
504
505 // </editor-fold>
506
507
508 // <editor-fold defaultstate="collapsed" desc=" == P a g i n a t i o n o f T a b l e L i s t i n g == " >
509
510 /**
511 * Show P a g i n a t i o n
512 *
513 * @param int $summ_number_of_items - total number of items
514 * @param int $active_page_num - number of activated page
515 * @param int $num_items_per_page - number of items per page
516 * @param array $only_these_parameters - array of keys to exclude from links
517 * @param string $url_sufix - usefule for anchor to HTML section with specific ID, Example: '#my_section'
518 */
519 function wpbc_show_pagination( $summ_number_of_items, $active_page_num, $num_items_per_page , $only_these_parameters = false, $url_sufix = '' ) {
520
521 if ( empty( $num_items_per_page ) ) {
522 $num_items_per_page = '10';
523 }
524
525 $pages_number = ceil( $summ_number_of_items / $num_items_per_page );
526 if ( $pages_number < 2 )
527 return;
528
529 //Fix: 5.1.4 - Just in case we are having tooo much resources, then we need to show all resources - and its empty string
530 // phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.NonceVerification.Missing, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
531 if ( ( isset( $_REQUEST['wh_booking_type'] ) ) && ( strlen( wp_unslash( $_REQUEST['wh_booking_type'] ) ) > 1000 ) ) {
532 $_REQUEST['wh_booking_type'] = '';
533 }
534
535 // First parameter will overwriten by $_GET['page'] parameter
536 $bk_admin_url = wpbc_get_params_in_url( wpbc_get_bookings_url( false, false ), array('page_num'), $only_these_parameters );
537
538
539 ?>
540 <span class="wpdevelop wpbc-pagination">
541 <div class="container-fluid">
542 <div class="row">
543 <div class="col-sm-12 text-center control-group0">
544 <nav class="btn-toolbar">
545 <div class="btn-group wpbc-no-margin" style="float:none;">
546
547 <?php
548 if ( $pages_number > 1 ) { ?>
549 <a class="button button-secondary <?php
550 echo ( $active_page_num == 1 ) ? ' disabled' : ''; ?>"
551 href="<?php
552 echo esc_url( $bk_admin_url ); ?>&page_num=<?php
553 if ( $active_page_num == 1 ) {
554 echo esc_attr( $active_page_num );
555 } else {
556 echo esc_attr( $active_page_num - 1 );
557 }
558 echo esc_attr( $url_sufix );
559 ?>">
560 <?php
561 esc_html_e( 'Prev', 'booking' ); ?>
562 </a>
563 <?php
564 }
565
566 /** Number visible pages (links) that linked to active page, other pages skipped by "..." */
567 $num_closed_steps = 3;
568
569 for ( $pg_num = 1; $pg_num <= $pages_number; $pg_num++ ) {
570
571 if ( ! (
572 ( $pages_number > ( $num_closed_steps * 4) )
573 && ( $pg_num > $num_closed_steps )
574 && ( ( $pages_number - $pg_num + 1 ) > $num_closed_steps )
575 && ( abs( $active_page_num - $pg_num ) > $num_closed_steps )
576 ) ) {
577 ?> <a class="button button-secondary <?php if ($pg_num == $active_page_num ) echo ' active'; ?>"
578 href="<?php echo esc_url( $bk_admin_url ); ?>&page_num=<?php echo esc_attr( $pg_num );
579 // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
580 echo $url_sufix; ?>">
581 <?php echo wp_kses_post( $pg_num ); ?>
582 </a><?php
583
584 if ( ( $pages_number > ( $num_closed_steps * 4) )
585 && ( ($pg_num+1) > $num_closed_steps )
586 && ( ( $pages_number - ( $pg_num + 1 ) ) > $num_closed_steps )
587 && ( abs($active_page_num - ( $pg_num + 1 ) ) > $num_closed_steps )
588 ) {
589 echo ' <a class="button button-secondary disabled" href="javascript:void(0);">...</a> ';
590 }
591 }
592 }
593
594 if ( $pages_number > 1 ) { ?>
595 <a class="button button-secondary <?php
596 echo ( $active_page_num == $pages_number ) ? ' disabled' : ''; ?>"
597 href="<?php
598 echo esc_url( $bk_admin_url ); ?>&page_num=<?php
599 if ( $active_page_num == $pages_number ) {
600 echo esc_attr( $active_page_num );
601 } else {
602 echo esc_attr( $active_page_num + 1 );
603 }
604 // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
605 echo $url_sufix; ?>">
606 <?php
607 esc_html_e( 'Next', 'booking' ); ?>
608 </a>
609 <?php
610 }
611 ?>
612
613 </div>
614 </nav>
615 </div>
616 </div>
617 </div>
618 </span>
619 <?php
620 }
621
622 // </editor-fold>
623
624
625 // <editor-fold defaultstate="collapsed" desc=" == Number of New Bookings == " >
626
627 /**
628 * Reset Cache for getting Number of new bookings. After this operation, system will get number of new bookings from the DB.
629 *
630 * @return void
631 */
632 function wpbc_booking_cache__new_bookings__reset(){
633 update_bk_option( 'booking_cache__new_bookings__saved_date', '' );
634 }
635 add_action( 'wpbc_track_new_booking', 'wpbc_booking_cache__new_bookings__reset' );
636 add_action( 'wpbc_set_booking_pending', 'wpbc_booking_cache__new_bookings__reset' );
637 add_action( 'wpbc_set_booking_approved', 'wpbc_booking_cache__new_bookings__reset' );
638 add_action( 'wpbc_move_booking_to_trash', 'wpbc_booking_cache__new_bookings__reset' );
639 add_action( 'wpbc_restore_booking_from_trash', 'wpbc_booking_cache__new_bookings__reset' );
640 add_action( 'wpbc_delete_booking_completely', 'wpbc_booking_cache__new_bookings__reset' );
641 add_action( 'wpbc_set_booking_as_read', 'wpbc_booking_cache__new_bookings__reset' );
642 add_action( 'wpbc_set_booking_as_unread', 'wpbc_booking_cache__new_bookings__reset' );
643
644
645 /**
646 * Get number of new bookings
647 * @return false|int|mixed|null
648 */
649 function wpbc_db_get_number_new_bookings() {
650
651 $new_bookings__number = get_bk_option( 'booking_cache__new_bookings__number' );
652 $new_bookings__saved_date = get_bk_option( 'booking_cache__new_bookings__saved_date' );
653
654 $nowdate_str_ymdhis = gmdate( 'Y-m-d H:i:s', strtotime( 'now' ) );
655
656 if ( ! empty( $new_bookings__saved_date ) ) {
657
658 $is_expired = ( strtotime( $new_bookings__saved_date ) <= strtotime( '-10 minutes', strtotime( $nowdate_str_ymdhis ) ) );
659
660 if ( ! $is_expired ) {
661 return $new_bookings__number;
662 }
663 }
664
665 global $wpdb;
666
667 $trash_bookings = ' AND bk.trash != 1 '; // FixIn: 6.1.1.10 - check also below usage of {$trash_bookings} .
668 $sql_req = "SELECT bk.booking_id FROM {$wpdb->prefix}booking as bk WHERE bk.is_new = 1 {$trash_bookings} ";
669
670 $sql_req = apply_bk_filter( 'get_sql_for_checking_new_bookings', $sql_req );
671 $sql_req = apply_bk_filter( 'get_sql_for_checking_new_bookings_multiuser', $sql_req );
672 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.NotPrepared
673 $bookings = $wpdb->get_results( $sql_req );
674 $bookings_count = count( $bookings );
675
676 update_bk_option( 'booking_cache__new_bookings__number', $bookings_count );
677 update_bk_option( 'booking_cache__new_bookings__saved_date', $nowdate_str_ymdhis );
678
679 return $bookings_count;
680 }
681
682
683 /**
684 * Update 'is_new' status of bookings in Database
685 *
686 * @param $id_of_new_bookings inr or comma seperated ID of bookings. Example: '1' | '3,5,7,9'
687 * @param $is_new '0' | '1'
688 * @param $user_id 'user_id'
689 *
690 */
691 function wpbc_db_update_number_new_bookings( $id_of_new_bookings, $is_new = '0', $user_id = 1 ) {
692
693 global $wpdb;
694
695 if ( count( $id_of_new_bookings ) > 0 ) {
696
697 $id_of_new_bookings = implode( ',', $id_of_new_bookings );
698 $id_of_new_bookings = wpbc_clean_like_string_for_db( $id_of_new_bookings );
699
700
701 if ( 'all' === $id_of_new_bookings ) {
702 $update_sql = "UPDATE {$wpdb->prefix}booking AS bk SET bk.is_new = {$is_new} WHERE bk.is_new != {$is_new} "; // FixIn: 8.2.1.18.
703
704 $update_sql = apply_bk_filter( 'update_sql_for_checking_new_bookings', $update_sql, 0, $user_id );
705 } else {
706 $update_sql = "UPDATE {$wpdb->prefix}booking AS bk SET bk.is_new = {$is_new} WHERE bk.booking_id IN ( {$id_of_new_bookings} ) ";
707 }
708
709 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.NotPrepared
710 if ( false === $wpdb->query( $update_sql ) ) {
711 debuge_error( 'Error during updating status of bookings at DB', __FILE__, __LINE__ );
712 die();
713 }
714 }
715 }
716
717 // </editor-fold>
718
719
720 // <editor-fold defaultstate="collapsed" desc=" == User ID | Role - functions == " >
721
722 /**
723 * Check if Current User have specific Role
724 *
725 * @return bool Whether the current user has the given capability.
726 */
727 function wpbc_is_current_user_have_this_role( $user_role ) {
728
729 if ( $user_role == 'administrator' ) $user_role = 'activate_plugins';
730 if ( $user_role == 'editor' ) $user_role = 'publish_pages';
731 if ( $user_role == 'author' ) $user_role = 'publish_posts';
732 if ( $user_role == 'contributor' ) $user_role = 'edit_posts';
733 if ( $user_role == 'subscriber') $user_role = 'read';
734
735 return current_user_can( $user_role );
736 }
737
738
739 /**
740 * Get Current ID of user or get user ID of Forced log in user in Booking Calendar MultiUser version.
741 *
742 * @return int
743 */
744 function wpbc_get_current_user_id() { // FixIn: 9.2.4.1.
745
746 if ( function_exists( 'wpbc_mu__wp_get_current_user' ) ) {
747 $user = wpbc_mu__wp_get_current_user();
748 $user_bk_id = $user->ID;
749 } else {
750 $user_bk_id = get_current_user_id();
751 }
752
753 return $user_bk_id;
754 }
755
756
757 /**
758 * Get Current User Object or get User object of Forced log in user in Booking Calendar MultiUser version.
759 *
760 * @return stdClass|WP_User|null
761 */
762 function wpbc_get_current_user() { // FixIn: 9.2.4.1.
763
764 if ( function_exists( 'wpbc_mu__wp_get_current_user' ) ) {
765 $user = wpbc_mu__wp_get_current_user();
766 } else {
767 $user = wp_get_current_user();
768 }
769
770 return $user;
771 }
772
773 // </editor-fold>
774
775
776 // <editor-fold defaultstate="collapsed" desc=" == Messages for Admin panel == " >
777
778
779 /**
780 * Show "Saved Changes" message at the top of settings page.
781 *
782 */
783 function wpbc_show_changes_saved_message() {
784 wpbc_show_message ( __('Changes saved.','booking'), 5 );
785 }
786
787
788 /**
789 * Show Message at Top of Admin Pages
790 *
791 * @param type $message - mesage to show
792 * @param type $time_to_show - number of seconds to show, if 0 or skiped, then unlimited time.
793 * @param type $message_type - Default: updated { updated | error | notice }
794 */
795 function wpbc_show_message ( $message, $time_to_show , $message_type = 'updated') {
796
797 // Generate unique HTML ID for the message
798 $inner_message_id = intval( time() * wp_rand(10, 100) );
799
800 // Get formated HTML message
801 $notice = wpbc_get_formated_message( $message, $message_type, $inner_message_id );
802
803 // Get the time of message showing
804 $time_to_show = intval( $time_to_show ) * 1000;
805
806 // Show this Message
807 ?> <script type="text/javascript">
808 if ( jQuery('.wpbc_admin_message').length ) {
809 jQuery('.wpbc_admin_message').append( '<?php
810 // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
811 echo $notice; ?>' );
812 <?php if ( $time_to_show > 0 ) { ?>
813 jQuery('#wpbc_inner_message_<?php echo esc_attr( $inner_message_id ); ?>').animate({opacity: 1},<?php echo esc_attr( $time_to_show ); ?>).fadeOut( 2000 );
814 <?php } ?>
815 }
816 </script> <?php
817 }
818
819
820 /**
821 * Escape and prepare message to show it
822 *
823 * @param type $message - message
824 * @param type $message_type - Default: updated { updated | error | notice }
825 * @param string $inner_message_id - ID of message DIV, can be skipped
826 * @return string
827 */
828 function wpbc_get_formated_message ( $message, $message_type = 'updated', $inner_message_id = '') {
829
830
831 // Recheck for any "lang" shortcodes for replacing to correct language
832 $message = wpbc_lang( $message );
833
834 // Escape any JavaScript from message
835 $notice = html_entity_decode( esc_js( $message ) ,ENT_QUOTES) ;
836
837 $notice .= '<a class="close tooltip_left" rel="tooltip" title="'. esc_js(__("Hide",'booking')). '" data-dismiss="alert" href="javascript:void(0)" onclick="javascript:jQuery(this).parent().hide();">&times;</a>';
838
839 if (! empty( $inner_message_id ))
840 $inner_message_id = 'id="wpbc_inner_message_'. $inner_message_id .'"';
841
842 $notice = '<div '.$inner_message_id.' class="wpbc_inner_message '. $message_type . '">' . $notice . '</div>';
843
844 return $notice;
845 }
846
847
848 /**
849 * Show system info in settings page
850 *
851 * @param string $message ...
852 * @param string $message_type 'info' | 'warning' | 'error'
853 * @param string $title __('Important!' ,'booking') | __('Note' ,'booking')
854 *
855 * Exmaple: wpbc_show_message_in_settings( __( 'Nothing Found', 'booking' ), 'warning', __('Important!' ,'booking') );
856 */
857 function wpbc_show_message_in_settings( $message, $message_type = 'info', $title = '' , $is_echo = true ) {
858
859 $message_content = '';
860
861 $message_content .= '<div class="clear"></div>';
862
863 $message_content .= '<div class="wpbc-settings-notice notice-' . $message_type . '" style="text-align:left;">';
864
865 if ( ! empty( $title ) )
866 $message_content .= '<strong>' . esc_js( $title ) . '</strong> ';
867
868 $message_content .= html_entity_decode( esc_js( $message ) ,ENT_QUOTES) ;
869
870 $message_content .= '</div>';
871
872 $message_content .= '<div class="clear"></div>';
873
874 if ( $is_echo ) {
875 // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
876 echo $message_content;
877 } else {
878 return $message_content;
879 }
880
881 }
882
883 // </editor-fold>
884
885
886 // <editor-fold defaultstate="collapsed" desc=" == Meta Boxes - Open/Close == " >
887
888 /**
889 * Meta box section open tag
890 *
891 * @param string $metabox_id HTML ID of section
892 * @param string $title Title in section
893 * @param array $params [
894 'is_section_visible_after_load' => true, // Default true - is this section Visible, after page loading or hidden - useful for Booking > Settings General page LEFT column sections
895 'is_show_minimize' => true // Default true - is show minimize button at top right section
896 ]
897 *
898 * @return void
899 */
900 function wpbc_open_meta_box_section( $metabox_id, $title, $params = array() ) {
901
902 $defaults = array(
903 'is_section_visible_after_load' => true,
904 'is_show_minimize' => true,
905 'dismiss_button' => '',
906 'css_class' => 'postbox'
907 );
908 $params = wp_parse_args( $params, $defaults );
909
910 $my_close_open_win_id = $metabox_id . '_metabox';
911
912 ?>
913 <div class='meta-box'>
914 <div id="<?php echo esc_attr( $my_close_open_win_id ); ?>"
915 class="<?php echo esc_attr( $params['css_class'] ); ?> <?php
916 if ( $params['is_show_minimize'] ) {
917 if ( '1' == get_user_option( 'booking_win_' . $my_close_open_win_id ) ) {
918 echo 'closed';
919 }
920 }
921 ?>"
922 style="<?php if ( ! $params['is_section_visible_after_load'] ) {
923 echo 'display:none';
924 }
925 ?>"
926 ><div class="postbox-header" style="display: flex;flex-flow: row nowrap;border-bottom: 1px solid #ccd0d4;">
927 <h3 class='hndle' style="flex: 1 1 auto;border: none;">
928 <span><?php
929 // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
930 echo $title;
931 ?></span>
932 <?php echo wp_kses_post( $params['dismiss_button'] ); ?>
933 </h3>
934 <?php if ( $params['is_show_minimize'] ) { ?>
935 <div title="<?php esc_attr_e('Click to toggle','booking'); ?>" class="handlediv"
936 onclick="javascript:wpbc_verify_window_opening(<?php echo esc_attr( wpbc_get_current_user_id() ); ?>, '<?php echo esc_attr( $my_close_open_win_id ); ?>');"
937 ><br/></div>
938 <?php } ?>
939 </div>
940 <div class="inside">
941 <?php
942 }
943
944
945 function wpbc_close_meta_box_section() {
946 ?>
947 </div>
948 </div>
949 </div>
950 <?php
951 }
952
953 // </editor-fold>
954
955
956 // <editor-fold defaultstate="collapsed" desc=" == Inline JavaScript to Footer page == " >
957
958 /**
959 * Queue JavaScript for later output at footer
960 *
961 * @param string $code
962 */
963 function wpbc_enqueue_js( $code ) {
964 global $wpbc_queued_js;
965
966 if ( empty( $wpbc_queued_js ) ) {
967 $wpbc_queued_js = '';
968 }
969
970 $wpbc_queued_js .= "\n" . $code . "\n";
971 }
972
973
974 /**
975 * Output any queued javascript code in the footer.
976 */
977 function wpbc_print_js() {
978
979 global $wpbc_queued_js;
980
981 if ( ! empty( $wpbc_queued_js ) ) {
982
983 $wpbc_queued_js = wp_check_invalid_utf8( $wpbc_queued_js );
984
985 $wpbc_queued_js = wp_specialchars_decode( $wpbc_queued_js, ENT_COMPAT ); // Converts double quotes '&quot;' => '"'.
986
987 $wpbc_queued_js = preg_replace( '/&#(x)?0*(?(1)27|39);?/i', "'", $wpbc_queued_js );
988 $wpbc_queued_js = str_replace( "\r", '', $wpbc_queued_js );
989
990 // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
991 echo "<!-- WPBC JavaScript -->\n<script type=\"text/javascript\">\njQuery(function($) {" . $wpbc_queued_js . "});\n</script>\n<!-- End WPBC JavaScript -->\n";
992
993 $wpbc_queued_js = '';
994 unset( $wpbc_queued_js );
995 }
996 }
997
998 // </editor-fold>
999
1000
1001 // <editor-fold defaultstate="collapsed" desc=" == Support functions for MU version == " >
1002
1003 /**
1004 * Set active User Environment in MultiUser version, depend from owner of booking resource
1005 *
1006 * @param int $previous_active_user (default=-1) - blank parameter
1007 * @param int $bktype - booking resource ID for checking
1008 * @return int - ID of Previous Active User
1009 *
1010 * Usage:
1011 $previous_active_user = apply_bk_filter('wpbc_mu_set_environment_for_owner_of_resource', -1, $bktype );
1012
1013 */
1014 function wpbc_mu_set_environment_for_owner_of_resource( $previous_active_user = -1, $bktype = 1 ) {
1015
1016 if ( class_exists( 'wpdev_bk_multiuser' ) ) {
1017 // Get the owner of this booking resource
1018 $user_bk_id = apply_bk_filter( 'get_user_of_this_bk_resource', false, $bktype );
1019
1020 $user = wpbc_get_current_user();
1021
1022 // Get possible other active user settings
1023 $previous_active_user = apply_bk_filter( 'get_client_side_active_params_of_user' );
1024
1025 // Set active user of that specific booking resource
1026 make_bk_action( 'check_multiuser_params_for_client_side_by_user_id', $user_bk_id );
1027 }
1028
1029 return $previous_active_user;
1030 }
1031 add_bk_filter('wpbc_mu_set_environment_for_owner_of_resource', 'wpbc_mu_set_environment_for_owner_of_resource');
1032
1033
1034 /**
1035 * Set environment for this user in MU version
1036 *
1037 * @param int $previous_active_user - ID of user
1038 * Usage:
1039 make_bk_action('wpbc_mu_set_environment_for_user', $previous_active_user );
1040
1041 */
1042 function wpbc_mu_set_environment_for_user( $previous_active_user ) {
1043
1044 if ( $previous_active_user !== -1 ) {
1045
1046 // Reactivate the previous active user
1047 make_bk_action('check_multiuser_params_for_client_side_by_user_id', $previous_active_user );
1048 }
1049 }
1050 add_bk_action('wpbc_mu_set_environment_for_user', 'wpbc_mu_set_environment_for_user');
1051
1052
1053 /**
1054 * Check if we have simulated user login in Booking Calendar MultiUser version
1055 * return user ID of regular simulated user or 0 if not simulated
1056 * @return int
1057 */
1058 function wpbc_mu__is_simulated_login_as_user(){
1059 if ( class_exists( 'wpdev_bk_multiuser' ) ) {
1060
1061 $real_current_user_id = get_current_user_id(); // Is current user suer booking admin and if this user was simulated log in
1062 $is_user_super_admin = apply_bk_filter( 'is_user_super_admin', $real_current_user_id );
1063 if ( $is_user_super_admin ) {
1064
1065 $simulate_user_id = intval( get_option( 'booking_simulate_login_as_user' ) ); // Is user was simulated log in
1066
1067 if ( ( ! empty( $simulate_user_id ) ) && ( $simulate_user_id > 0 ) ) {
1068 return $simulate_user_id;
1069 }
1070 }
1071 }
1072 return 0;
1073 }
1074 // </editor-fold>
1075
1076
1077 // <editor-fold defaultstate="collapsed" desc=" == Currency functions (>=BS) == " >
1078
1079 /**
1080 * Format booking cost with a currency symbol.
1081 * In MultiUser version also checking about specific currency that belong to specific WordPress user.
1082 * This checking based on belonging specific booking resource to specific user.
1083 *
1084 * @param float $cost
1085 * @param int $booking_resource_id
1086 * @return string - $cost_to_show_with_currency
1087 */
1088 function wpbc_get_cost_with_currency_for_user( $cost, $booking_resource_id = 0 ){
1089
1090 if ( ( $cost === '' ) || ( ! class_exists( 'wpdev_bk_biz_s' ) ) ) {
1091 return '';
1092 }
1093
1094 if ( ! empty( $booking_resource_id ) ) {
1095 $previous_active_user = apply_bk_filter( 'wpbc_mu_set_environment_for_owner_of_resource', - 1, $booking_resource_id );
1096 } // MU
1097
1098 $cost_to_show_with_currency = wpbc_cost_show( $cost, array( 'currency' => wpbc_get_currency() ) );
1099
1100 if ( ! empty( $booking_resource_id ) ) {
1101 make_bk_action( 'wpbc_mu_set_environment_for_user', $previous_active_user );
1102 } // MU
1103
1104 return $cost_to_show_with_currency;
1105 }
1106
1107
1108 /**
1109 * Get currency Symbol.
1110 * In MultiUser version also checking about specific currency that belong to specific WordPress user.
1111 * This checking based on belonging specific booking resource to specific user.
1112 *
1113 * @param int $booking_resource_id - ID of specific booking resource
1114 * @return string - currency symbol
1115 */
1116 function wpbc_get_currency_symbol_for_user( $booking_resource_id = 0 ){
1117
1118 if ( ! class_exists( 'wpdev_bk_biz_s' ) ) {
1119 return '';
1120 }
1121
1122 if ( ! empty( $booking_resource_id ) ) {
1123 $previous_active_user = apply_bk_filter( 'wpbc_mu_set_environment_for_owner_of_resource', - 1, $booking_resource_id );
1124 } // MU
1125
1126 $currency_symbol = wpbc_get_currency_symbol();
1127
1128 if ( ! empty( $booking_resource_id ) ) {
1129 make_bk_action( 'wpbc_mu_set_environment_for_user', $previous_active_user );
1130 } // MU
1131
1132 return $currency_symbol;
1133 }
1134
1135 /**
1136 * Get Cost per period: DAY / NIGHT / FIXED / HOUR
1137 * In MultiUser version This checking based on belonging specific booking resource to specific user.
1138 *
1139 * @param int $booking_resource_id - ID of specific booking resource
1140 * @return string - cost per period
1141 */
1142 function wpbc_get_cost_per_period_for_user( $booking_resource_id = 0 ){ // FixIn: 10.0.0.14.
1143
1144 if ( ! class_exists( 'wpdev_bk_biz_s' ) ) {
1145 return '';
1146 }
1147
1148 if ( ! empty( $booking_resource_id ) ) {
1149 $previous_active_user = apply_bk_filter( 'wpbc_mu_set_environment_for_owner_of_resource', - 1, $booking_resource_id );
1150 } // MU
1151
1152 $cost_period = get_bk_option( 'booking_paypal_price_period' );
1153
1154 if ( ! empty( $booking_resource_id ) ) {
1155 make_bk_action( 'wpbc_mu_set_environment_for_user', $previous_active_user );
1156 } // MU
1157
1158 return $cost_period;
1159 }
1160 // </editor-fold>
1161
1162
1163 // <editor-fold defaultstate="collapsed" desc=" == Approve | Pending functions == " >
1164
1165 /**
1166 * Check is this booking approved -- get booking dates in DB and check status
1167 *
1168 * @param $booking_id
1169 *
1170 * @return bool
1171 */
1172 function wpbc_is_booking_approved( $booking_id ) {
1173 // FixIn: 8.1.2.8.
1174
1175 $is_booking_approved = false;
1176
1177 global $wpdb;
1178
1179 $sql = $wpdb->prepare( "SELECT DISTINCT approved FROM {$wpdb->prefix}bookingdates WHERE booking_id = %d ORDER BY booking_date", $booking_id );
1180 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.NotPrepared
1181 $dates_result = $wpdb->get_results( $sql );
1182
1183 foreach ( $dates_result as $my_date ) {
1184
1185 if ( 1 === intval( $my_date->approved ) ) {
1186 $is_booking_approved = true; // FixIn: 8.3.1.2.
1187 }
1188 }
1189
1190 return $is_booking_approved;
1191 }
1192
1193
1194 /**
1195 * Approve booking in DB (update booking dates in DB like approved = '1')
1196 *
1197 * @param $booking_id int | CSD e.g. 100 | '1,5,10'
1198 *
1199 * @return bool
1200 */
1201 function wpbc_db__booking_approve( $booking_id ) {
1202
1203 $booking_id = wpbc_clean_digit_or_csd( $booking_id ); // Check parameter if it number or comma separated list of numbers.
1204
1205 global $wpdb;
1206
1207 $update_sql = "UPDATE {$wpdb->prefix}bookingdates SET approved = '1' WHERE booking_id IN ({$booking_id});";
1208
1209 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.NotPrepared
1210 if ( false === $wpdb->query( $update_sql ) ) {
1211 return false;
1212 }
1213
1214 // In case if the booking was in Trash, then restore it.
1215 // FixIn: 10.8.1.1.
1216
1217 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.PreparedSQL.InterpolatedNotPrepared
1218 if ( false === $wpdb->query( "UPDATE {$wpdb->prefix}booking AS bk SET bk.trash = 0 WHERE booking_id IN ({$booking_id})" ) ) {
1219 return false;
1220 }
1221
1222 return true;
1223 }
1224
1225
1226 /**
1227 * Approve specific booking and send email about this.
1228 *
1229 * @param int $booking_id - ID of booking
1230 * @param string $email_reason
1231 */
1232 function wpbc_auto_approve_booking( $booking_id , $email_reason = '' ) {
1233
1234 $booking_id = wpbc_clean_digit_or_csd( $booking_id ); // Check paramter if it number or comma separated list of numbers
1235
1236 if ( is_numeric( $booking_id ) ) { // FixIn: 8.1.2.8.
1237 if ( ! wpbc_is_booking_approved( $booking_id ) ) {
1238 do_action( 'wpbc_booking_approved', $booking_id, 1 ); // FixIn: 8.7.6.1.
1239
1240 wpbc_send_email_approved( $booking_id, 1, $email_reason );
1241 }
1242 } else {
1243 $booking_id_arr = explode( ',',$booking_id );
1244 foreach ( $booking_id_arr as $bk_id ) {
1245 if ( ! wpbc_is_booking_approved( $bk_id ) ) {
1246 do_action( 'wpbc_booking_approved', $bk_id, 1 ); // FixIn: 8.7.6.1.
1247 wpbc_send_email_approved( $bk_id, 1, $email_reason );
1248 }
1249 }
1250 }
1251
1252 $db_result = wpbc_db__booking_approve( $booking_id );
1253
1254 if ( false === $db_result ){
1255
1256 wpbc_redirect( site_url() );
1257 }
1258 }
1259
1260
1261 /**
1262 * Set as Pending specific booking and send email about this.
1263 *
1264 * @param int $booking_id - ID of booking
1265 * @param string $denyreason
1266 */
1267 function wpbc_auto_pending_booking( $booking_id, $denyreason = '' ) {
1268 // FixIn: 8.4.7.25.
1269
1270 global $wpdb;
1271
1272 $booking_id = wpbc_clean_digit_or_csd( $booking_id ); // Check paramter if it number or comma separated list of numbers.
1273
1274 if ( is_numeric( $booking_id ) ) { // FixIn: 8.1.2.8.
1275 if ( wpbc_is_booking_approved( $booking_id ) ) {
1276 wpbc_send_email_deny( $booking_id, 1, $denyreason );
1277 }
1278 } else {
1279 $booking_id_arr = explode( ',', $booking_id );
1280 foreach ( $booking_id_arr as $bk_id ) {
1281 if ( wpbc_is_booking_approved( $bk_id ) ) {
1282 wpbc_send_email_deny( $bk_id, 1, $denyreason );
1283 }
1284 }
1285 }
1286
1287 $update_sql = "UPDATE {$wpdb->prefix}bookingdates SET approved = '0' WHERE booking_id IN ({$booking_id});";
1288 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.NotPrepared
1289 if ( false === $wpdb->query( $update_sql ) ) {
1290
1291 wpbc_redirect( site_url() );
1292 }
1293 }
1294
1295
1296 /**
1297 * Cancel (move to Trash) specific booking.
1298 *
1299 * @param int $booking_id - ID of booking
1300 * @param string $email_reason - reason of cancellation
1301 */
1302 function wpbc_auto_cancel_booking( $booking_id, $email_reason = '' ) {
1303 // FixIn: 8.4.7.25.
1304
1305 global $wpdb;
1306
1307 $booking_id = wpbc_clean_digit_or_csd( $booking_id ); // Check paramter if it number or comma separated list of numbers.
1308
1309 if ( empty( $email_reason ) ) { // FixIn: 8.4.7.25.
1310 // Get the reason of cancellation.
1311 $email_reason = __( 'Payment rejected', 'booking' );
1312 $auto_cancel_pending_unpaid_bk_is_send_email = get_bk_option( 'booking_auto_cancel_pending_unpaid_bk_is_send_email' );
1313 if ( 'On' === $auto_cancel_pending_unpaid_bk_is_send_email ) {
1314 $email_reason = get_bk_option( 'booking_auto_cancel_pending_unpaid_bk_email_reason' );
1315 }
1316 }
1317 // Send decline emails.
1318 wpbc_send_email_trash( $booking_id, 1, $email_reason );
1319 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.PreparedSQL.InterpolatedNotPrepared
1320 if ( false === $wpdb->query( "UPDATE {$wpdb->prefix}booking AS bk SET bk.trash = 1 WHERE booking_id IN ({$booking_id})" ) ) {
1321
1322 wpbc_redirect( site_url() );
1323 }
1324 }
1325
1326
1327 // FixIn: 9.9.0.43.
1328
1329 /**
1330 * Auto approve booking and send email, after successful payment process
1331 *
1332 * It resolves issue in Booking Calendar MultiUser version for sending "regular email" to visitors, if was made booking for booking resource, that belong to regular user,
1333 * and was activated this option "Receive all payments only to Super Booking Admin account" at the WP Booking Calendar > Settings General page in "Multiuser Options" section
1334 *
1335 * @param $booking_id
1336 *
1337 * @return void
1338 */
1339 function wpbc_auto_approve_booking__after_payment( $booking_id ) {
1340 //-------------------------------------------------------------------------------------------------- // FixIn: 9.9.0.43.
1341 $is_force_again = false;
1342 if ( class_exists( 'wpdev_bk_multiuser' ) ) {
1343
1344 list( $booking_hash, $booking_resource_id ) = wpbc_hash__get_booking_hash__resource_id( $booking_id );
1345
1346 $user_id = apply_bk_filter( 'get_user_of_this_bk_resource', false, $booking_resource_id );
1347
1348 $is_booking_resource_user_super_admin = apply_bk_filter( 'is_user_super_admin', $user_id );
1349
1350 if (
1351 ( 'On' == get_bk_option( 'booking_super_admin_receive_regular_user_payments' ) )
1352 && ( ! $is_booking_resource_user_super_admin )
1353 ) {
1354 // Finish "Super-User" forcing
1355 make_bk_action( 'finish_force_using_this_user' );
1356 //Reactivate data for "regular user
1357 make_bk_action( 'check_multiuser_params_for_client_side_by_user_id', $user_id );
1358
1359 $is_force_again = true;
1360 }
1361 }
1362 // -------------------------------------------------------------------------------------------------
1363
1364 wpbc_auto_approve_booking( $booking_id );
1365
1366 if ( $is_force_again ) { // FixIn: 9.9.0.43.
1367 make_bk_action( 'make_force_using_this_user', - 999 ); // '-999' - This ID "by default" is the ID of super booking admin user
1368 }
1369 }
1370
1371
1372 /**
1373 * Auto cancel booking and send email, after successful payment process
1374 *
1375 * It resolves issue in Booking Calendar MultiUser version for sending "regular email" to visitors, if was made booking for booking resource, that belong to regular user,
1376 * and was activated this option "Receive all payments only to Super Booking Admin account" at the WP Booking Calendar > Settings General page in "Multiuser Options" section
1377 *
1378 * @param $booking_id
1379 *
1380 * @return void
1381 */
1382 function wpbc_auto_cancel_booking__after_payment( $booking_id ) {
1383 //-------------------------------------------------------------------------------------------------- // FixIn: 9.9.0.43.
1384 $is_force_again = false;
1385 if ( class_exists( 'wpdev_bk_multiuser' ) ) {
1386
1387 list( $booking_hash, $booking_resource_id ) = wpbc_hash__get_booking_hash__resource_id( $booking_id );
1388
1389 $user_id = apply_bk_filter( 'get_user_of_this_bk_resource', false, $booking_resource_id );
1390
1391 $is_booking_resource_user_super_admin = apply_bk_filter( 'is_user_super_admin', $user_id );
1392
1393 if (
1394 ( 'On' == get_bk_option( 'booking_super_admin_receive_regular_user_payments' ) )
1395 && ( ! $is_booking_resource_user_super_admin )
1396 ) {
1397 // Finish "Super-User" forcing
1398 make_bk_action( 'finish_force_using_this_user' );
1399 //Reactivate data for "regular user
1400 make_bk_action( 'check_multiuser_params_for_client_side_by_user_id', $user_id );
1401
1402 $is_force_again = true;
1403 }
1404 }
1405 // -------------------------------------------------------------------------------------------------
1406
1407 wpbc_auto_cancel_booking( $booking_id );
1408
1409 if ( $is_force_again ) { // FixIn: 9.9.0.43.
1410 make_bk_action( 'make_force_using_this_user', - 999 ); // '-999' - This ID "by default" is the ID of super booking admin user
1411 }
1412 }
1413 // </editor-fold>
1414
1415
1416 // <editor-fold defaultstate="collapsed" desc=" == Logs for Notes / remarks == " >
1417
1418 /**
1419 * Add Log info to Notes of bookings
1420 *
1421 * @param array | int $booking_id_arr
1422 * @param string $message
1423 */
1424 function wpbc_db__add_log_info( $booking_id_arr, $message ) {
1425
1426 if ( get_bk_option( 'booking_log_booking_actions' ) !== 'On' ) {
1427 return;
1428 }
1429
1430 $booking_id_arr = (array) $booking_id_arr;
1431
1432 $is_append = true;
1433 foreach ( $booking_id_arr as $booking_id ) {
1434 $date_time = date_i18n( '[Y-m-d H:i] ' );
1435 make_bk_action('wpdev_make_update_of_remark' , $booking_id , $date_time . $message , $is_append ); // FixIn: 9.1.2.14.
1436 }
1437 }
1438
1439 // </editor-fold>
1440
1441
1442 // <editor-fold defaultstate="collapsed" desc=" == CSV export support function == " >
1443
1444 /**
1445 * Get Path from request URL. E.g. 'my-category/file.csv' from url, like https://server.com/my-category/file.csv
1446 *
1447 * It can detect internal sub folder or WordPress, like http://server.com/my-website/
1448 *
1449 * @return false|string
1450 */
1451 function wpbc_get_request_url_path(){
1452
1453 $server_request_uri = ( ( isset( $_SERVER['REQUEST_URI'] ) ) ? sanitize_text_field( $_SERVER['REQUEST_URI'] ) : '' ); /* phpcs:ignore WordPress.Security.NonceVerification.Missing, WordPress.Security.ValidatedSanitizedInput.MissingUnslash */ /* FixIn: sanitize_unslash */
1454 $my_parsed_url = wp_parse_url( $server_request_uri );
1455
1456 if ( false === $my_parsed_url ) { // seriously malformed URLs, wp_parse_url() may return FALSE.
1457 return false;
1458 }
1459
1460 $my_parsed_url_path = trim( $my_parsed_url['path'] );
1461 $my_parsed_url_path = trim( $my_parsed_url_path, '/' );
1462
1463
1464 // Check internal sub folder of WP, like http://server.com/my-website/[ ... LINK ...] // FixIn: 2.0.5.4.
1465 if ( function_exists( 'wp_parse_url' ) ) {
1466 $wp_home_server_url = wp_parse_url( home_url() );
1467 } else {
1468 $wp_home_server_url = @wp_parse_url( home_url() );
1469 }
1470
1471 if ( ( false !== $wp_home_server_url ) && ( ! empty( $wp_home_server_url['path'] ) ) ) { // seriously malformed URLs, wp_parse_url() may return FALSE.
1472
1473 $server_url_sufix = trim( $wp_home_server_url[ 'path' ] ); // [path] => /my-website
1474 $server_url_sufix = trim( $server_url_sufix, '/' ); // my-website
1475
1476 if ( ! empty( $server_url_sufix ) ) {
1477
1478 $check_sufix = substr( $my_parsed_url_path, 0, strlen( $server_url_sufix ) );
1479
1480 if ( $check_sufix === $server_url_sufix ) {
1481
1482 $my_parsed_url_path = substr( $my_parsed_url_path, strlen( $server_url_sufix ) );
1483
1484 $my_parsed_url_path = trim( $my_parsed_url_path, '/' );
1485 }
1486 }
1487 } //End FixIn: 2.0.5.4
1488
1489 return $my_parsed_url_path;
1490 }
1491
1492 // </editor-fold>
1493
1494
1495 // <editor-fold defaultstate="collapsed" desc=" == SKIP BLANK EMAIL == " >
1496
1497
1498 /**
1499 * Check if this email is NOT blank email to SKIP email sending -- from autofill fast booking creation at Booking > Add booking page.
1500 *
1501 * Currently, plugin use 'blank@wpbookingmanager.com' for all blank bookings, previously it was used 'admin@blank.com'
1502 *
1503 * @param $email_address
1504 * @param $email_content
1505 *
1506 * @return bool
1507 */
1508 function wpbc_is_not_blank_email( $email_address, $email_content ) {
1509
1510 // Previously: if ( ( strpos( $to, '@blank.com' ) === false ) && ( strpos( $replace['content'], 'admin@blank.com' ) === false ) ) { ->send(...) }
1511
1512 if (
1513 ( false === strpos( $email_address, '@blank.com' ) )
1514 && ( false === strpos( $email_content, 'admin@blank.com' ) )
1515 && ( false === strpos( $email_address, '@wpbookingmanager.com' ) )
1516 && ( false === strpos( $email_content, 'blank@wpbookingmanager.com' ) )
1517 ) {
1518 return true;
1519 }
1520
1521 return false;
1522 }
1523
1524 // </editor-fold>
1525
1526
1527 // <editor-fold defaultstate="collapsed" desc=" == PHP PERFORMANCE == " >
1528
1529
1530 /**
1531 * Start calculation of time for execution of specific part of CODE
1532 *
1533 * @param string $name name of section
1534 * @param array $php_performance
1535 *
1536 * @return array
1537 *
1538 * Example:
1539 *
1540 * $php_performance = php_performance_START( 'emails_sending' , $php_performance );
1541 *
1542 * ... some code here ...
1543 *
1544 * $php_performance = php_performance_END( 'emails_sending' , $php_performance );
1545 *
1546 * echo 'Time of execution: ' . $php_performancep['emails_sending']
1547 *
1548 */
1549 function php_performance_START( $name, $php_performance ) {
1550
1551 if ( empty( $php_performance ) ) {
1552 $php_performance = array();
1553 }
1554
1555 $php_performance[ $name ] = microtime( true );
1556
1557 return $php_performance;
1558 }
1559
1560 /**
1561 * End calculation of time for execution of specific part of CODE
1562 *
1563 * @param string $name name of section
1564 * @param array $php_performance
1565 *
1566 * @return array
1567 *
1568 * Example:
1569 *
1570 * $php_performance = php_performance_START( 'emails_sending' , $php_performance );
1571 *
1572 * ... some code here ...
1573 *
1574 * $php_performance = php_performance_END( 'emails_sending' , $php_performance );
1575 *
1576 * echo 'Time of execution: ' . $php_performancep['emails_sending']
1577 *
1578 */
1579 function php_performance_END( $name, $php_performance ) {
1580
1581 if ( empty( $php_performance ) ) {
1582 $php_performance = array();
1583 }
1584 if ( empty( $php_performance[ $name ] ) ) {
1585 $php_performance[ $name ] = microtime( true );
1586 }
1587
1588 $php_performance[ $name ] = microtime( true ) - $php_performance[ $name ];
1589
1590 return $php_performance;
1591 }
1592
1593 /**
1594 * Set maximum number of seconds for execution.
1595 *
1596 * @param $limit_in_seconds_int
1597 *
1598 * @return void
1599 */
1600 function wpbc_set_limit_php( $limit_in_seconds_int = 300 ) {
1601
1602 WPBC_Action_Scheduler_Compatibility::raise_memory_limit();
1603 WPBC_Action_Scheduler_Compatibility::raise_time_limit( $limit_in_seconds_int );
1604 }
1605
1606
1607 // </editor-fold>