PluginProbe
Booking Manager – Sync WP Booking Calendar – Import Events, Export Bookings to ICS Calendar / trunk
Booking Manager – Sync WP Booking Calendar – Import Events, Export Bookings to ICS Calendar vtrunk
2.1.20 2.1.4 2.1.5 2.1.6 2.1.7 2.1.8 2.1.9 trunk 1.1 2.0 2.0.1 2.0.10.2 2.0.11 2.0.12 2.0.13 2.0.14 2.0.15 2.0.16 2.0.17 2.0.18 2.0.2 2.0.20 2.0.21 2.0.22 2.0.23 All 54 releases
booking-manager / core / wpbm-functions.php

wpbm-functions.php in Booking Manager – Sync WP Booking Calendar – Import Events, Export Bookings to ICS Calendar trunk, at core/wpbm-functions.php

2,030 lines 71.8 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 Manager
5 * @subpackage Support Functions
6 * @category Functions
7 *
8 * @author wpdevelop
9 * @link https://oplugins.com/
10 * @email info@oplugins.com
11 *
12 * @modified 29.09.2015
13 */
14
15 if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
16
17
18 // <editor-fold defaultstate="collapsed" desc=" V e r s i o n s " >
19 ////////////////////////////////////////////////////////////////////////////////
20 // V e r s i o n s
21 ////////////////////////////////////////////////////////////////////////////////
22
23 /** Get version
24 *
25 * @return string
26 */
27 function get_wpbm_version(){
28 $version = 'free';
29 return $version;
30 }
31
32 /** Check if user accidentially update Booking Manager Paid version to Free
33 *
34 * @return bool
35 */
36 function wpbm_is_updated_paid_to_free() {
37
38 if ( ( wpbm_is_table_exists('wpbm_log') ) && ( ! class_exists('wpbm_personal') ) )
39 return true;
40 else
41 return false;
42 }
43
44 function wpbm_get_ver_sufix() {
45
46 if ( strpos( strtolower( WPBM_VERSION ), 'multisite' ) !== false ) {
47 $v_type = '-multi';
48 } else if ( strpos( strtolower( WPBM_VERSION ), 'develop' ) !== false ) {
49 $v_type = '-dev';
50 } else {
51 $v_type = '';
52 }
53 $v = '';
54 if ( class_exists( 'wpbm_personal' ) )
55 $v = 'ps' . $v_type;
56 if ( class_exists( 'wpbm_pro' ) )
57 $v = '';
58 return $v;
59 }
60
61 function wpbm_up_link() {
62 if ( ! wpbm_is_this_demo() )
63 $v = wpbm_get_ver_sufix();
64 else $v = '';
65 return 'https://oplugins.com/plugins/booking-manager/' . ( ( empty($v) ) ? '' : 'upgrade-' . $v . '/' ) ;
66 }
67
68 /** Check if this demo website
69 *
70 * @return bool
71 */
72 function wpbm_is_this_demo() {
73 //return ! true; //TODO: comment it. 2016-09-27 // Replaced!
74 if (
75 ( ( isset( $_SERVER['SCRIPT_FILENAME'] ) ) && ( strpos( sanitize_text_field( wp_unslash($_SERVER['SCRIPT_FILENAME']) ), 'oplugins.com' ) !== false ) )
76 || ( ( isset( $_SERVER['HTTP_HOST'] ) ) && ( strpos( sanitize_text_field( wp_unslash($_SERVER['HTTP_HOST'])), 'oplugins.com' ) !== false ) )
77 )
78 return true;
79 else
80 return false;
81 }
82
83 /** Get Warning Text for Demo websites */
84 function wpbm_get_warning_text_in_demo_mode() {
85
86 return '<div class="wpbm-settings-notice notice-warning"><strong>Warning!</strong> Demo test version does not allow changes to these items.</div>';
87 }
88
89 /** Show System Info (status) at item > Settings General page
90 * Link: http://server.com/wp-admin/admin.php?page=wpbm-settings&system_info=show#wpbm_general_settings_system_info_metabox
91 */
92 function wpbm_system_info() {
93 echo '---';
94 }
95
96
97
98 /** Check if "Booking Calendar" installed/activated and return version number
99 *
100 * @return string - 0 if not installed, otherwise version num
101 */
102 function wpbm_get_wpbc_version() {
103
104 if ( ! defined( 'WP_BK_VERSION_NUM' ) )
105 return 0;
106 else
107 return WP_BK_VERSION_NUM;
108 }
109
110 /** Is activated Booking Calendar support WPBM
111 *
112 * @return boolean
113 */
114 function wpbm_is_wpbc_supported() {
115
116 // 7.2.1 - its start version of Booking Calendar which support integration with Booking Manager 2.0
117
118 if ( version_compare( wpbm_get_wpbc_version(), '9.8') >= 0 ) {
119 return true;
120 } else {
121 return false;
122 }
123 }
124
125 // </editor-fold>
126
127
128 // <editor-fold defaultstate="collapsed" desc=" F o r m a t t i n g " >
129 ////////////////////////////////////////////////////////////////////////////////
130 // F o r m a t t i n g
131 ////////////////////////////////////////////////////////////////////////////////
132 /**
133 * Sanitize term to Slug format (no spaces, lowercase).
134 * urldecode - reverse munging of UTF8 characters.
135 *
136 * @param mixed $value
137 * @return string
138 */
139 function wpbm_get_slug_format( $value ) {
140 return urldecode( sanitize_title( $value ) );
141 }
142
143 /**
144 * Get Slug Format Option Value for saving to the options table.
145 * Replacing - to _ and restrict length to 64 characters.
146 *
147 * @param string $value
148 * @return string
149 */
150 function wpbm_get_slug_format_4_option_name( $value ) {
151
152 $value = wpbm_get_slug_format( $value );
153 $value = str_replace('-', '_', $value);
154 $value = substr($value, 0, 64);
155 return $value;
156 }
157
158 /** Insert New Line symbols after <br> tags. Usefull for the settings pages to show in redable view
159 *
160 * @param type $param
161 * @return type
162 */
163 function wpbm_nl_after_br($param) {
164
165 $value = preg_replace( "@(&lt;|<)br\s*/?(&gt;|>)(\r\n)?@", "<br/>", $param );
166
167 return $value;
168 }
169
170 /**
171 * Replace ** to <strong> and * to <em>
172 *
173 * @param String $text
174 * @return string
175 */
176 if ( ! function_exists( 'wpbm_recheck_strong_symbols' ) ) {
177 function wpbm_recheck_strong_symbols( $text ){
178
179 $patterns = '/(\*\*)(\s*[^\*\*]*)(\*\*)/';
180 $replacement = '<strong>${2}</strong>';
181 $value_return = preg_replace($patterns, $replacement, $text);
182
183 $patterns = '/(\*)(\s*[^\*]*)(\*)/';
184 $replacement = '<em>${2}</em>';
185 $value_return = preg_replace($patterns, $replacement, $value_return);
186
187 return $value_return;
188 }
189 }
190
191
192 /** Esacpe and replace any HTML entities
193 *
194 * @param type $string
195 * @return string
196 */
197 function wpbm_esc_to_plain_text( $string ) {
198
199 // //Replace <a href="http://server.com">Link</a> to Link( http://server.com )
200 // $pattern = "/<a(.*)+href=[\"|']+([^\"']+)(?=(\"|'))[^>]*>(.*)<\/a>/" ; //"/(?<=href=(\"|'))[^\"']+(?=(\"|'))/i";
201 // $newurl = "$4 ($2)";
202 // $string = preg_replace($pattern,$newurl,$string);
203
204
205 // List of preg* regular expression patterns to search for replace in plain emails. More: https://raw.github.com/ushahidi/wp-silcc/master/class.html2text.inc
206 $plain_search_array = array(
207 "/\r/", // Non-legal carriage return
208 '/&(nbsp|#160);/i', // Non-breaking space
209 '/&(quot|rdquo|ldquo|#8220|#8221|#147|#148|#34|#034);/i', // Double quotes //FixIn: 2.0.1.6
210 '/&(apos|rsquo|lsquo|#8216|#8217|#39|#039);/i', // Single quotes //FixIn: 2.0.1.6
211 '/&gt;/i', // Greater-than
212 '/&lt;/i', // Less-than
213 '/&#38;/i', // Ampersand
214 '/&#038;/i', // Ampersand
215 '/&amp;/i', // Ampersand
216 '/&(copy|#169);/i', // Copyright
217 '/&(trade|#8482|#153);/i', // Trademark
218 '/&(reg|#174);/i', // Registered
219 '/&(mdash|#151|#8212);/i', // mdash
220 '/&(ndash|minus|#8211|#8722);/i', // ndash
221 '/&(bull|#149|#8226);/i', // Bullet
222 '/&(pound|#163);/i', // Pound sign
223 '/&(euro|#8364);/i', // Euro sign
224 '/&#36;/', // Dollar sign
225 '/&[^&;]+;/i', // Unknown/unhandled entities
226 '/[ ]{2,}/' // Runs of spaces, post-handling
227 );
228
229 // List of symbols for Replace
230 $get_plain_replace_array = array(
231 '', // Non-legal carriage return
232 ' ', // Non-breaking space
233 '"', // Double quotes
234 "'", // Single quotes
235 '>', // Greater-than
236 '<', // Less-than
237 '&', // Ampersand
238 '&', // Ampersand
239 '&', // Ampersand
240 '(c)', // Copyright
241 '(tm)', // Trademark
242 '(R)', // Registered
243 '--', // mdash
244 '-', // ndash
245 '*', // Bullet
246 '£', // Pound sign
247 'EUR', // Euro sign. € ?
248 '$', // Dollar sign
249 '', // Unknown/unhandled entities
250 ' ' // Runs of spaces, post-handling
251 );
252
253 $newstring = preg_replace( $plain_search_array, $get_plain_replace_array, wp_strip_all_tags( $string ) );
254
255 return $newstring;
256 }
257 // </editor-fold>
258
259
260 // <editor-fold defaultstate="collapsed" desc=" S u p p o r t " >
261 ////////////////////////////////////////////////////////////////////////////////
262 // S u p p o r t Functions
263 ////////////////////////////////////////////////////////////////////////////////
264
265 /** Replace shortcodes in string
266 *
267 * @param string $subject - string to manipulate
268 * @param array $replace_array - array with values to replace // array( [wpbm_id] => 9, [id] => 9, [dates] => July 3, 2016 14:00 - July 4, 2016 16:00, .... )
269 * @param mixed $replace_unknown_shortcodes - replace unknown params, if false, then no replace unknown params
270 * @return string
271 */
272 function wpbm_replace_shortcodes( $subject, $replace_array , $replace_unknown_shortcodes = ' ' ) {
273
274 $defaults = array(
275 'ip' => apply_wpbm_filter( 'wpbm_get_user_ip' )
276 , 'blogname' => wp_specialchars_decode( get_option( 'blogname' ), ENT_QUOTES )
277 , 'siteurl' => get_site_url()
278 );
279
280 $replace = wp_parse_args( $replace_array, $defaults );
281
282 foreach ( $replace as $replace_shortcode => $replace_value ) {
283
284 $replace_value = esc_js( $replace_value ); // FixIn:
285
286 $subject = str_replace( array( '[' . $replace_shortcode . ']'
287 , '{' . $replace_shortcode . '}' )
288 , $replace_value
289 , $subject );
290 }
291
292 // Remove all shortcodes, which is not replaced early.
293 if ( $replace_unknown_shortcodes !== false )
294 $subject = preg_replace( '/[\s]{0,}[\[\{]{1}[a-zA-Z][0-9a-zA-Z:._-]{0,}[\]\}]{1}[\s]{0,}/', $replace_unknown_shortcodes, $subject );
295
296
297 return $subject;
298 }
299
300
301 /**
302 * Sanitize the frontend listing template.
303 *
304 * The listing template is stored as an option and rendered by the public
305 * [booking-manager-listing] shortcode, so script-capable markup must never be
306 * persisted or returned to visitors.
307 *
308 * @param string $template Template HTML with Booking Manager placeholders.
309 * @return string Safe template HTML.
310 */
311 function wpbm_sanitize_listing_template( $template ) {
312
313 if ( ! is_string( $template ) ) {
314 $template = '';
315 }
316
317 $allowed_html = wp_kses_allowed_html( 'post' );
318
319 // Keep compatibility with templates that embed safe external content.
320 $allowed_html['iframe'] = array(
321 'src' => true
322 , 'style' => true
323 , 'id' => true
324 , 'class' => true
325 , 'width' => true
326 , 'height' => true
327 , 'title' => true
328 , 'loading' => true
329 , 'allowfullscreen' => true
330 );
331
332 if ( isset( $allowed_html['a'] ) ) {
333 $allowed_html['a']['target'] = true;
334 $allowed_html['a']['rel'] = true;
335 }
336
337 return wp_kses( $template, $allowed_html );
338 }
339
340 /** Simple hack to make array strings lowercase
341 *
342 * @param type $array
343 * @return type
344 */
345 function wpbm_arraytolower( $array ){
346 return unserialize( strtolower( serialize( $array ) ) );
347 }
348
349 /** Support 'hash_equals' this function at older servers than PHP 5.6.0 */
350 if ( !function_exists( 'hash_equals' ) ) {
351 function hash_equals( $known_string, $user_string ) {
352 $ret = 0;
353
354 if ( strlen( $known_string ) !== strlen( $user_string ) ) {
355 $user_string = $known_string;
356 $ret = 1;
357 }
358
359 $res = $known_string ^ $user_string;
360
361 for ( $i = strlen( $res ) - 1; $i >= 0; --$i ) {
362 $ret |= ord( $res[$i] );
363 }
364
365 return !$ret;
366 }
367 }
368
369 /** Check if this valid timestamp
370 *
371 * @param string|int $timestamp
372 * @return bool
373 */
374 function wpbm_is_valid_timestamp( $timestamp ) {
375 return ( ( (string) (int) $timestamp === $timestamp)
376 && ($timestamp <= PHP_INT_MAX)
377 && ($timestamp >= ~PHP_INT_MAX)
378 );
379 }
380 // </editor-fold>
381
382
383 // <editor-fold defaultstate="collapsed" desc=" F i l e s && U R L s " >
384 ////////////////////////////////////////////////////////////////////////////////
385 // F i l e s && U R L s
386 ////////////////////////////////////////////////////////////////////////////////
387
388 /** Get absolute URL to relative plugin path.
389 * Depend from the WPBM_MIN contant can be load minified version of file, if its exist
390 * @param string $path - path
391 * @return string
392 */
393 function wpbm_plugin_url( $path ) {
394
395 if ( ( defined( 'WPBM_MIN' ) ) && ( WPBM_MIN ) ){
396 $path_min = $path;
397 if ( substr( $path_min , -3 ) === '.js' ) {
398 $path_min = substr( $path_min , 0, -3 ) . '.min.js';
399 }
400 if ( substr( $path_min , -4 ) === '.css' ) {
401 $path_min = substr( $path_min , 0, -4 ) . '.min.css';
402 }
403 if ( file_exists( trailingslashit( WPBM_PLUGIN_DIR ) . ltrim( $path_min, '/\\' ) ) ) // check if this file exist
404 return trailingslashit( WPBM_PLUGIN_URL ) . ltrim( $path_min, '/\\' );
405 }
406 return trailingslashit( WPBM_PLUGIN_URL ) . ltrim( $path, '/\\' );
407 }
408
409 /** Check if such file exist or not.
410 *
411 * @param string $path - relative path to file (relative to plugin folder).
412 * @return boolean true | false
413 */
414 function wpbm_is_file_exist( $path ) {
415
416 if ( file_exists( trailingslashit( WPBM_PLUGIN_DIR ) . ltrim( $path, '/\\' ) ) ) // check if this file exist
417 return true;
418 else
419 return false;
420 }
421
422 /** Set URL from absolute to relative (starting from /)
423 *
424 * @param type $url
425 * @return type
426 */
427 function wpbm_set_relative_url( $url ){
428
429 $url = esc_url_raw($url);
430
431 $url_path = parse_url($url, PHP_URL_PATH);
432 $url_path = ( empty($url_path) ? $url : $url_path );
433
434 $url = trim($url_path, '/');
435 return '/' . $url;
436 }
437
438 /** Get Correct Relative URL
439 *
440 * @param type $link
441 * @return string
442 */
443 function wpbm_make_link_relative( $link ){
444
445 if ( $link == get_option('siteurl') )
446 $link = '/';
447 $link = '/' . trim( wp_make_link_relative( $link ), '/' );
448
449 return $link;
450 }
451
452 /** Get Correct Absolute URL
453 *
454 * @param string $link
455 * @return type
456 */
457 function wpbm_make_link_absolute( $link ){
458
459 if ( ( $link != get_option('siteurl') ) && ( strpos($link, 'http') !== 0 ) )
460 $link = get_option('siteurl') . '/' . trim( wp_make_link_relative( $link ), '/' );
461 return esc_js( $link ) ;
462 }
463
464
465 if (!function_exists ('get_file_data_wpdev')) {
466
467 /** Get header info from this file, just for compatibility with WordPress 2.8 and older versions
468 *
469 * @param type $file
470 * @param type $default_headers
471 * @param type $context
472 * @return type
473 */
474 function get_file_data_wpdev( $file, $default_headers, $context = '' ) {
475 // We don't need to write to the file, so just open for reading.
476 $fp = fopen( $file, 'r' ); // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_fopen
477
478 // Pull only the first 8kiB of the file in.
479 $file_data = fread( $fp, 8192 );// phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_fread
480
481 // PHP will close file handle, but we are good citizens.
482 fclose( $fp );// phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_fclose
483
484 if( $context != '' ) {
485 $extra_headers = array(); //apply_filters( "extra_$context".'_headers', array() );
486
487 $extra_headers = array_flip( $extra_headers );
488 foreach( $extra_headers as $key=>$value ) {
489 $extra_headers[$key] = $key;
490 }
491 $all_headers = array_merge($extra_headers, $default_headers);
492 } else {
493 $all_headers = $default_headers;
494 }
495
496 foreach ( $all_headers as $field => $regex ) {
497 preg_match( '/' . preg_quote( $regex, '/' ) . ':(.*)$/mi', $file_data, ${$field});
498 if ( !empty( ${$field} ) )
499 ${$field} = trim(preg_replace("/\s*(?:\*\/|\?>).*/", '', ${$field}[1] ));
500 else
501 ${$field} = '';
502 }
503
504 $file_data = compact( array_keys( $all_headers ) );
505
506 return $file_data;
507 }
508 }
509
510
511 /** Get content from specific URL
512 *
513 * @param string $url
514 * @return string|boolean (false on error)
515 */
516 function wpbm_get_ssl_page_content( $url ) {
517
518 $request = new WP_Http();
519
520 $result = $request->request( $url
521 , array( // Default Parameters
522 'reject_unsafe_urls' => true, //FixIn: 2.0.29.1
523 'user-agent' => 'Mozilla/5.0 (iPad; U; CPU OS 3_2_1 like Mac OS X; en-us) AppleWebKit/531.21.10 (KHTML, like Gecko) Mobile/7B405' //FixIn: 2.0.12.1
524 // 'method' => 'GET',
525 // 'timeout' => 5, // timeout value for an HTTP request.
526 // 'redirection' => 5, // number of redirects allowed during an HTTP request.
527 // 'httpversion' => '1.0',
528 // 'user-agent' => 'WordPress/' . get_bloginfo( 'version' ) . '; ' . get_bloginfo( 'url' ),
529 // 'reject_unsafe_urls' => false,
530 // 'blocking' => true,
531 // 'headers' => array(),
532 // 'cookies' => array(),
533 // 'body' => null,
534 // 'compress' => false,
535 // 'decompress' => true,
536 // 'sslverify' => true,
537 // 'sslcertificates' => ABSPATH . WPINC . '/certificates/ca-bundle.crt',
538 // 'stream' => false,
539 // 'filename' => null,
540 // 'limit_response_size' => null
541 )
542 );
543
544 if (
545 ( ! is_wp_error( $result ) )
546 && ( $result[ 'response' ][ 'code' ] == '200' )
547 ) {
548
549 return $result[ 'body' ];
550
551 } else {
552
553 //FixIn: 2.0.2.2
554 if ( is_wp_error( $result ) ) {
555 $error_message = $result->get_error_message();
556 } else {
557 $error_message = __( 'Unknown error during downloading feed', 'booking-manager' );
558
559 // Show more detail info of not ability to download .ics feeds. //FixIn: 2.0.10.5
560 $error_message .= $result[ 'body' ];
561 //do_action( 'wpbc_admin_show_top_notice', $error_message, 'error', 5000 );
562 //die;
563 }
564 do_action( 'wpbc_admin_show_top_notice', $error_message, 'error', 5000 ); // N_O_T_I_C_E in H_E_A_D_E_R
565 // debuge($error_message); //FixIn: 2.0.1.3 //FixIn: 2.0.8.2
566
567 return false;
568 }
569 }
570
571
572
573 /** Count the number of bytes of a given string.
574 * Input string is expected to be ASCII or UTF-8 encoded.
575 * Warning: the function doesn't return the number of chars
576 * in the string, but the number of bytes.
577 * See http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
578 * for information on UTF-8.
579 *
580 * @param string $str The string to compute number of bytes
581 *
582 * @return The length in bytes of the given string.
583 */
584 function wpbm_get_bytes_from_str( $str ) {
585 // STRINGS ARE EXPECTED TO BE IN ASCII OR UTF-8 FORMAT
586 // Number of characters in string
587 $strlen_var = strlen( $str );
588
589 $d = 0; // string bytes counter
590
591 // Iterate over every character in the string, escaping with a slash or encoding to UTF-8 where necessary
592 for ( $c = 0; $c < $strlen_var; ++ $c ) {
593 $ord_var_c = ord( $str[$c] ); //FixIn: 2.0.17.1
594 switch ( true ) {
595 case(($ord_var_c >= 0x20) && ($ord_var_c <= 0x7F)): // characters U-00000000 - U-0000007F (same as ASCII)
596 $d ++;
597 break;
598 case(($ord_var_c & 0xE0) == 0xC0): // characters U-00000080 - U-000007FF, mask 110XXXXX
599 $d += 2;
600 break;
601 case(($ord_var_c & 0xF0) == 0xE0): // characters U-00000800 - U-0000FFFF, mask 1110XXXX
602 $d += 3;
603 break;
604 case(($ord_var_c & 0xF8) == 0xF0): // characters U-00010000 - U-001FFFFF, mask 11110XXX
605 $d += 4;
606 break;
607 case(($ord_var_c & 0xFC) == 0xF8): // characters U-00200000 - U-03FFFFFF, mask 111110XX
608 $d += 5;
609 break;
610 case(($ord_var_c & 0xFE) == 0xFC): // characters U-04000000 - U-7FFFFFFF, mask 1111110X
611 $d += 6;
612 break;
613 default:
614 $d ++;
615 }
616 }
617 return $d;
618 }
619
620
621 // </editor-fold>
622
623
624 // <editor-fold defaultstate="collapsed" desc=" A d m i n M e n u L i n k s " >
625 ////////////////////////////////////////////////////////////////////////////
626 // A d m i n M e n u L i n k s
627 ////////////////////////////////////////////////////////////////////////////
628
629 /** Get URL to specific Admin Menu page
630 *
631 * @param string $menu_type - { item | add | resources | settings }
632 * @param boolean $is_absolute_url - Absolute or relative url { default: true }
633 * @return string - URL to menu
634 */
635 function wpbm_get_menu_url( $menu_type, $is_absolute_url = true ) {
636
637 switch ( $menu_type) {
638
639 case 'master': // Master
640 $link = 'oplugins&tab=wpbm';
641 break;
642
643 case 'add': // Add New
644 case 'new': // Add New
645 $link = 'oplugins&wpbm-new';
646 break;
647
648 case 'settings': // Settings
649 case 'options':
650 $link = 'oplugins&tab=wpbm-settings';
651 break;
652
653 default: // Master
654 $link = 'oplugins';
655 break;
656 }
657
658 if ( $is_absolute_url ) {
659 $link = admin_url( 'admin.php' ) . '?page=' . $link ;
660 }
661
662 return $link;
663 }
664
665 // // // // // // // // // // // // // // // // // // // // // // // // // /
666
667 /** Get URL of item Listing or Calendar Overview page
668 *
669 * @param boolean $is_absolute_url - Absolute or relative url { default: true }
670 * @param boolean $is_old - { default: true }
671 * @return string - URL to menu
672 */
673 function wpbm_get_master_url( $is_absolute_url = true ) {
674 return wpbm_get_menu_url( 'master', $is_absolute_url );
675 }
676
677 /** Get URL of item > Add item page
678 *
679 * @param boolean $is_absolute_url - Absolute or relative url { default: true }
680 * @param boolean $is_old - { default: true }
681 * @return string - URL to menu
682 */
683 function wpbm_get_new_wpbm_url( $is_absolute_url = true ) {
684 return wpbm_get_menu_url( 'add', $is_absolute_url );
685 }
686
687 /** Get URL of item > Settings page
688 *
689 * @param boolean $is_absolute_url - Absolute or relative url { default: true }
690 * @param boolean $is_old - { default: true }
691 * @return string - URL to menu
692 */
693 function wpbm_get_settings_url( $is_absolute_url = true ) {
694 return wpbm_get_menu_url( 'settings', $is_absolute_url );
695 }
696
697 // // // // // // // // // // // // // // // // // // // // // // // // // /
698
699 /** Check if this item Listing or Calendar Overview page
700 * @param string $server_param - 'REQUEST_URI' | 'HTTP_REFERER' Default: 'REQUEST_URI'
701 * @return boolean true | false
702 */
703 function wpbm_is_master_page( $server_param = 'REQUEST_URI' ) {
704
705 if ( ( is_admin() ) && isset($_SERVER[ $server_param ]) &&
706 ( strpos(sanitize_text_field( wp_unslash($_SERVER[ $server_param ])),'page=oplugins') !== false ) && // phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.NonceVerification.Missing, WordPress.Security.ValidatedSanitizedInput.InputNotValidated
707 ( strpos(sanitize_text_field( wp_unslash($_SERVER[ $server_param ])),'tab=wpbm-') === false ) && // not the settings // phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.NonceVerification.Missing, WordPress.Security.ValidatedSanitizedInput.InputNotValidated
708 ( ( strpos(sanitize_text_field( wp_unslash($_SERVER[ $server_param ])),'tab=wpbm') !== false ) // tab specified // phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.NonceVerification.Missing, WordPress.Security.ValidatedSanitizedInput.InputNotValidated
709 || ( strpos(sanitize_text_field( wp_unslash($_SERVER[ $server_param ])),'tab=') === false ) ) // or tab not specified at all // phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.NonceVerification.Missing, WordPress.Security.ValidatedSanitizedInput.InputNotValidated
710 ) {
711 return true;
712 }
713 return false;
714 }
715
716 /** Check if this item > Add item page
717 * @param string $server_param - 'REQUEST_URI' | 'HTTP_REFERER' Default: 'REQUEST_URI'
718 * @return boolean true | false
719 */
720 function wpbm_is_new_wpbm_page( $server_param = 'REQUEST_URI' ) {
721
722 if ( ( is_admin() ) && isset($_SERVER[ $server_param ]) &&
723 ( strpos(sanitize_text_field( wp_unslash($_SERVER[ $server_param ])),'page=oplugins') !== false ) && // phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.NonceVerification.Missing, WordPress.Security.ValidatedSanitizedInput.InputNotValidated
724 ( strpos(sanitize_text_field( wp_unslash($_SERVER[ $server_param ])),'tab=wpbm-new') !== false ) // phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.NonceVerification.Missing, WordPress.Security.ValidatedSanitizedInput.InputNotValidated
725 ) {
726 return true;
727 }
728 return false;
729 }
730
731
732 /** Check if this item > Settings page
733 * @param string $server_param - 'REQUEST_URI' | 'HTTP_REFERER' Default: 'REQUEST_URI'
734 * @return boolean true | false
735 */
736 function wpbm_is_settings_page( $server_param = 'REQUEST_URI' ) {
737
738 if ( ( is_admin() ) && isset($_SERVER[ $server_param ]) &&
739 ( strpos(sanitize_text_field( wp_unslash($_SERVER[ $server_param ])),'page=oplugins') !== false ) && // phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.NonceVerification.Missing, WordPress.Security.ValidatedSanitizedInput.InputNotValidated
740 ( strpos(sanitize_text_field( wp_unslash($_SERVER[ $server_param ])),'tab=wpbm-settings') !== false ) // phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.NonceVerification.Missing, WordPress.Security.ValidatedSanitizedInput.InputNotValidated
741 ) {
742 return true;
743 }
744 return false;
745 }
746
747 // </editor-fold>
748
749
750 // <editor-fold defaultstate="collapsed" desc=" A d m i n U I E l e m e n t s " >
751 ////////////////////////////////////////////////////////////////////////////
752 // A d m i n U I E l e m e n t s
753 ////////////////////////////////////////////////////////////////////////////
754
755 /** Get Number of new items
756 *
757 * @return int
758 */
759 function wpbm_get_number_new_items(){
760 return 0;
761 }
762
763
764 /** Show Admin B A R .
765 *
766 * @global type $wp_admin_bar
767 * @return type
768 */
769 function wp_admin_bar_items_menu(){
770
771 global $wp_admin_bar;
772
773 $current_user = wp_get_current_user();
774
775 $curr_user_role = get_wpbm_option( 'wpbm_user_role_master' );
776 $level = 10;
777 if ($curr_user_role == 'administrator') $level = 10;
778 else if ($curr_user_role == 'editor') $level = 7;
779 else if ($curr_user_role == 'author') $level = 2;
780 else if ($curr_user_role == 'contributor') $level = 1;
781 else if ($curr_user_role == 'subscriber') $level = 0;
782
783 if ( ( $current_user->user_level < $level ) || ! is_admin_bar_showing() )
784 return;
785
786
787 $update_count = wpbm_get_number_new_items(); // 0
788
789 $title = 'Booking Manager';
790 $update_title = $title;
791
792
793 if ( $update_count > 0 ) {
794 $update_count_title = "&nbsp;<span class='wpbm-count bk-update-count' style='background: #f0f0f1;color: #2c3338;display: inline;padding: 2px 5px;font-weight: 600;border-radius: 10px;'>" . number_format_i18n($update_count) . "</span>" ; //id='wpbm-count'
795 $update_title .= $update_count_title;
796 }
797
798 $link_items = wpbm_get_master_url();
799 $link_settings = wpbm_get_settings_url();
800
801
802 $wp_admin_bar->add_menu(
803 array(
804 'id' => 'bar_wpbm',
805 'title' => $update_title ,
806 'href' => wpbm_get_master_url()
807 )
808 );
809
810
811 $curr_user_role_settings = get_wpbm_option( 'wpbm_user_role_settings' );
812 $level = 10;
813 if ($curr_user_role_settings == 'administrator') $level = 10;
814 else if ($curr_user_role_settings == 'editor') $level = 7;
815 else if ($curr_user_role_settings == 'author') $level = 2;
816 else if ($curr_user_role_settings == 'contributor') $level = 1;
817 else if ($curr_user_role_settings == 'subscriber') $level = 0;
818
819 if ( ( ($current_user->user_level < $level) ) || !is_admin_bar_showing() ) return;
820
821 $wp_admin_bar->add_menu(
822 array(
823 'id' => 'bar_wpbm_new',
824 'title' => __( 'Add New', 'booking-manager'),
825 'href' => wpbm_get_new_wpbm_url(),
826 'parent' => 'bar_wpbm',
827 )
828 );
829
830
831
832 $wp_admin_bar->add_menu(
833 array(
834 'id' => 'bar_wpbm_settings',
835 'title' => __( 'Settings', 'booking-manager'),
836 'href' => wpbm_get_settings_url(),
837 'parent' => 'bar_wpbm',
838 )
839 );
840
841 $wp_admin_bar->add_menu(
842 array(
843 'id' => 'bar_wpbm_settings_email',
844 'title' => __( 'Emails', 'booking-manager'),
845 'href' => $link_settings . '&tab=email',
846 'parent' => 'bar_wpbm_settings'
847 )
848 );
849
850 }
851 // add_action( 'admin_bar_menu', 'wp_admin_bar_items_menu', 70 ); // Add Admin Bar
852
853
854 /** Show Rating link at footer */
855 function wpbm_show_wpbm_footer(){
856
857 // Nothing here.
858 }
859 // </editor-fold>
860
861
862 // <editor-fold defaultstate="collapsed" desc=" DB - cheking if table, field or index exists " >
863 ////////////////////////////////////////////////////////////////////////////
864 // DB - cheking if table, field or index exists
865 ////////////////////////////////////////////////////////////////////////////
866
867 /**
868 * Check if table exist
869 *
870 * @global type $wpdb
871 * @param string $tablename
872 * @return 0|1
873 */
874 function wpbm_is_table_exists( $tablename ) {
875
876 global $wpdb;
877
878 if ( ( ! empty( $wpdb->prefix ) ) && ( strpos( $tablename, $wpdb->prefix ) === false ) ) {
879 $tablename = $wpdb->prefix . $tablename;
880 }
881
882
883
884 $res = $wpdb->get_results( $wpdb->prepare( "SHOW TABLES LIKE %s", $tablename ) ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
885
886 return count( $res ); //FixIn 5.4.3.
887 }
888
889
890 /**
891 * Check if table exist
892 *
893 * @global type $wpdb
894 * @param string $tablename
895 * @param type $fieldname
896 * @return 0|1
897 */
898 function wpbm_is_field_in_table_exists( $tablename , $fieldname) {
899 global $wpdb;
900 if ( (! empty($wpdb->prefix) ) && ( strpos($tablename, $wpdb->prefix) === false ) ) $tablename = $wpdb->prefix . $tablename ;
901 $sql_check_table = "SHOW COLUMNS FROM {$tablename}" ;
902
903 $res = $wpdb->get_results( $sql_check_table ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.NotPrepared, PluginCheck.Security.DirectDB.UnescapedDBParameter
904
905 foreach ($res as $fld) {
906 if ($fld->Field == $fieldname) return 1;
907 }
908
909 return 0;
910 }
911
912
913 /**
914 * Check if index exist
915 *
916 * @global type $wpdb
917 * @param string $tablename
918 * @param type $fieldindex
919 * @return 0|1
920 */
921 function wpbm_is_index_in_table_exists( $tablename , $fieldindex) {
922 global $wpdb;
923 if ( (! empty($wpdb->prefix) ) && ( strpos($tablename, $wpdb->prefix) === false ) ) $tablename = $wpdb->prefix . $tablename ;
924
925 $res = $wpdb->get_results( $wpdb->prepare("SHOW INDEX FROM {$tablename} WHERE Key_name = %s", $fieldindex ) ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.InterpolatedNotPrepared
926 if (count($res)>0) return 1;
927 else return 0;
928 }
929
930 // </editor-fold>
931
932
933 // <editor-fold defaultstate="collapsed" desc=" E s c a p i n g " >
934 ////////////////////////////////////////////////////////////////////////////
935 // E s c a p i n g
936 ////////////////////////////////////////////////////////////////////////////
937
938 /** Transform the REQESTS parameters (GET and POST) into URL
939 *
940 * @param type $page_param
941 * @param array $exclude_params
942 * @param type $only_these_parameters
943 * @return type
944 */
945 function wpbm_get_params_in_url( $page_param , $exclude_params = array(), $only_these_parameters = false, $is_escape_url = false, $only_get = false ){
946
947 $exclude_params[] = 'page';
948
949 // phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.NonceVerification.Missing, WordPress.Security.ValidatedSanitizedInput.InputNotValidated, WordPress.Security.ValidatedSanitizedInput.MissingUnslash, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
950 if ( isset( $_GET['page'] ) ) { $page_param = $_GET['page']; }
951
952 $get_paramaters = array( 'page' => $page_param );
953
954 if ( $only_get )
955 $check_params = $_GET; // phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.NonceVerification.Missing, WordPress.Security.ValidatedSanitizedInput.InputNotValidated, WordPress.Security.ValidatedSanitizedInput.MissingUnslash, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
956 else
957 $check_params = $_REQUEST; // phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.NonceVerification.Missing, WordPress.Security.ValidatedSanitizedInput.InputNotValidated, WordPress.Security.ValidatedSanitizedInput.MissingUnslash, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
958 //debuge($check_params);
959 foreach ( $check_params as $prm_key => $prm_value ) {
960
961 // Skip parameters arrays, like $_GET['rvaluation_to'] = Array ( [0] => 6, [1] => 14, [2] => 14 )
962 if (
963 ( is_string( $prm_value ) )
964 || ( is_numeric( $prm_value ) )
965 ) {
966
967 if ( strlen( $prm_value ) > 1000 ) { // Check about TOOO long parameters, if it exist then reset it.
968 $prm_value = '';
969 }
970
971 if ( ! in_array( $prm_key, $exclude_params ) )
972 if ( ( $only_these_parameters === false ) || ( in_array( $prm_key, $only_these_parameters ) ) )
973 $get_paramaters[ $prm_key ] = $prm_value;
974 }
975 }
976 //debuge($check_params, $get_paramaters, $exclude_params );
977 $url = admin_url( add_query_arg( $get_paramaters , 'admin.php' ) );
978
979 if ( $is_escape_url )
980 $url = esc_url( $url );
981
982 return $url;
983
984 /* // Old variant:
985 if ( isset( $_GET['page'] ) ) $page_param = $_GET['page'];
986
987 $url_start = 'admin.php?page=' . $page_param . '&';
988 $exclude_params[] = 'page';
989 foreach ( $_REQUEST as $prm_key => $prm_value ) {
990
991 if ( !in_array( $prm_key, $exclude_params ) )
992 if ( ($only_these_parameters === false) || ( in_array( $prm_key, $only_these_parameters ) ) )
993
994 $url_start .= $prm_key . '=' . $prm_value . '&';
995
996 }
997 $url_start = substr( $url_start, 0, -1 );
998
999 return $url_start;
1000 */
1001 }
1002
1003
1004 /** Clean Request Parameters
1005 *
1006 */
1007 function wpbm_check_request_paramters() {
1008
1009 $clean_params = array();
1010
1011 $clean_params[ 'wh_wpbm_id' ] = 'digit_or_csd'; // '0' | '1' | ''
1012 $clean_params[ 'wh_wpbm_date' ] = 'digit_or_date'; // number | date 2016-07-20
1013 $clean_params[ 'wh_wpbm_datenext' ] = 'd'; // '1' | '2' ....
1014 $clean_params[ 'wh_pay_statuscustom' ] = 's'; //string !!! LIKE !!!
1015 $clean_params[ 'wh_pay_status' ] = array( 'all', 'group_ok', 'group_unknown', 'group_pending', 'group_failed' );
1016
1017 foreach ( $clean_params as $request_key => $clean_type ) {
1018
1019 // elements only listed in array::
1020 if ( is_array( $clean_type ) ) { // check only values from the list in this array
1021
1022 if ( ( isset( $_REQUEST[ $request_key ] ) ) && ( ! in_array( $_REQUEST[ $request_key ], $clean_type ) ) ) // phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.NonceVerification.Missing, WordPress.Security.ValidatedSanitizedInput.InputNotValidated, WordPress.Security.ValidatedSanitizedInput.MissingUnslash, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
1023 $clean_type = 's';
1024 else
1025 $clean_type = 'checked_skip_it';
1026 }
1027
1028 switch ( $clean_type ) {
1029
1030 case 'checked_skip_it':
1031
1032 break;
1033
1034 case 'digit_or_date': // digit or comma separated digit
1035 // phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.NonceVerification.Missing, WordPress.Security.ValidatedSanitizedInput.InputNotValidated, WordPress.Security.ValidatedSanitizedInput.MissingUnslash, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
1036 if ( isset( $_REQUEST[ $request_key ] ) ) { $_REQUEST[ $request_key ] = wpbm_clean_digit_or_date( $_REQUEST[ $request_key ] ); } // nums
1037
1038 break;
1039
1040 case 'digit_or_csd': // digit or comma separated digit
1041 // phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.NonceVerification.Missing, WordPress.Security.ValidatedSanitizedInput.InputNotValidated, WordPress.Security.ValidatedSanitizedInput.MissingUnslash, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
1042 if ( isset( $_REQUEST[ $request_key ] ) ) { $_REQUEST[ $request_key ] = wpbm_clean_digit_or_csd( $_REQUEST[ $request_key ] ); } // nums
1043
1044 break;
1045
1046 case 's': // string
1047 // phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.NonceVerification.Missing, WordPress.Security.ValidatedSanitizedInput.InputNotValidated, WordPress.Security.ValidatedSanitizedInput.MissingUnslash, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
1048 if ( isset( $_REQUEST[ $request_key ] ) ) { $_REQUEST[ $request_key ] = wpbm_clean_like_string_for_db( $_REQUEST[ $request_key ] ); }
1049
1050 break;
1051
1052 case 'd': // digit
1053 // phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.NonceVerification.Missing, WordPress.Security.ValidatedSanitizedInput.InputNotValidated, WordPress.Security.ValidatedSanitizedInput.MissingUnslash, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
1054 if (( isset( $_REQUEST[ $request_key ] ) ) && ( $_REQUEST[ $request_key ] !== '' )) { $_REQUEST[ $request_key ] = intval( $_REQUEST[ $request_key ] ); }
1055
1056 break;
1057
1058 default:
1059 // phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.NonceVerification.Missing, WordPress.Security.ValidatedSanitizedInput.InputNotValidated, WordPress.Security.ValidatedSanitizedInput.MissingUnslash, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
1060 if ( isset( $_REQUEST[ $request_key ] ) ) { $_REQUEST[ $request_key ] = intval( $_REQUEST[ $request_key ] ); }
1061 break;
1062 }
1063
1064
1065 }
1066
1067 }
1068
1069
1070 /** Check paramter if it number or comma separated list of numbers
1071 *
1072 * @global type $wpdb
1073 * @param string $value
1074 * @return string
1075 *
1076 * Exmaple:
1077 wpbm_clean_digit_or_csd( '12,a,45,9' ) => '12,0,45,9'
1078 * or
1079 wpbm_clean_digit_or_csd( '10a' ) => '10
1080 * or
1081 wpbm_clean_digit_or_csd( array( '12,a,45,9', '10a' ) ) => array ( '12,0,45,9', '10' )
1082 */
1083 function wpbm_clean_digit_or_csd( $value ) { //FixIn:6.2.1.4
1084
1085 if ( $value === '' ) return $value;
1086
1087
1088 if ( is_array( $value ) ) {
1089 foreach ( $value as $key => $check_value ) {
1090 $value[ $key ] = wpbm_clean_digit_or_csd( $check_value );
1091 }
1092 return $value;
1093 }
1094
1095
1096 global $wpdb;
1097
1098 $value = str_replace( ';', ',', $value );
1099
1100 $array_of_nums = explode(',', $value);
1101
1102 $result = array();
1103 foreach ($array_of_nums as $check_element) {
1104 $result[] = $wpdb->prepare( "%d", $check_element );
1105 }
1106 $result = implode(',', $result );
1107 return $result;
1108 }
1109
1110
1111 /** Cehck about Valid date, like 2016-07-20 or digit
1112 *
1113 * @param string $value
1114 * @return string or int
1115 */
1116 function wpbm_clean_digit_or_date( $value ) { //FixIn:6.2.1.4
1117
1118 if ( $value === '' ) return $value;
1119
1120 if ( preg_match("/^[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])$/", $value ) ) {
1121
1122 return $value; // Date is valid in format: 2016-07-20
1123 } else {
1124 return intval( $value );
1125 }
1126
1127 }
1128
1129
1130 /** Check $value for injection here
1131 *
1132 * @param type $value
1133 * @return type
1134 */
1135 function wpbm_clean_parameter( $value ) {
1136
1137 $value = preg_replace( '/<[^>]*>/', '', $value ); // clean any tags
1138 $value = str_replace( '<', ' ', $value );
1139 $value = str_replace( '>', ' ', $value );
1140 $value = wp_strip_all_tags( $value );
1141
1142 // Clean SQL injection
1143 $value = esc_sql( $value );
1144
1145 return $value;
1146 }
1147
1148
1149 function wpbm_esc_like( $value_trimmed ) {
1150
1151 global $wpdb;
1152 if ( method_exists( $wpdb ,'esc_like' ) )
1153 return $wpdb->esc_like( $value_trimmed ); // Its require minimum WP 4.0.0
1154 else
1155 return addcslashes( $value_trimmed, '_%\\' ); // Direct implementation from $wpdb->esc_like(
1156 }
1157
1158
1159 /** Clean user string for using in SQL LIKE statement - append to LIKE sql
1160 *
1161 * @param string $value - to clean
1162 * @return string - escaped
1163 * Exmaple:
1164 * $search_escaped_like_title = wpbm_clean_like_string_for_append_in_sql_for_db( $input_var );
1165 *
1166 * $where_sql = " WHERE title LIKE ". $search_escaped_like_title ." ";
1167 */
1168 function wpbm_clean_like_string_for_append_in_sql_for_db( $value ) {
1169 global $wpdb;
1170
1171 $value_trimmed = trim( stripslashes( $value ) );
1172 $wild = '%';
1173 $like = $wild . wpbm_esc_like( $value_trimmed ) . $wild;
1174 $sql = $wpdb->prepare( "'%s'", $like ); // phpcs:ignore WordPress.DB.PreparedSQLPlaceholders.QuotedSimplePlaceholder
1175
1176 return $sql;
1177
1178
1179 /* Help:
1180 * First half of escaping for LIKE special characters % and _ before preparing for MySQL.
1181 * Use this only before wpdb::prepare() or esc_sql(). Reversing the order is very bad for security.
1182 *
1183 * Example Prepared Statement:
1184 *
1185 * $wild = '%';
1186 * $find = 'only 43% of planets';
1187 * $like = $wild . wpbm_esc_like( $find ) . $wild;
1188 * $sql = $wpdb->prepare( "SELECT * FROM $wpdb->posts WHERE post_content LIKE '%s'", $like );
1189 *
1190 * Example Escape Chain:
1191 *
1192 * $sql = esc_sql( wpbm_esc_like( $input ) );
1193 */
1194
1195 }
1196
1197
1198 /** Clean string for using in SQL LIKE requests inside single quotes: WHERE title LIKE '%". $escaped_search_title ."%'
1199 * Replaced _ to \_ % to \% \ to \\
1200 * @param string $value - to clean
1201 * @return string - escaped
1202 * Exmaple:
1203 * $search_escaped_like_title = wpbm_clean_like_string_for_db( $input_var );
1204 *
1205 * $where_sql = " WHERE title LIKE '%". $search_escaped_like_title ."%' ";
1206 *
1207 * Important! Use SINGLE quotes after in SQL query: LIKE '%".$data."%'
1208 */
1209 function wpbm_clean_like_string_for_db( $value ){
1210
1211 global $wpdb;
1212
1213 $value_trimmed = trim( stripslashes( $value ) );
1214
1215 $value_trimmed = wpbm_esc_like( $value_trimmed );
1216
1217 $value = trim( $wpdb->prepare( "'%s'", $value_trimmed ) , "'" ); // phpcs:ignore WordPress.DB.PreparedSQLPlaceholders.QuotedSimplePlaceholder
1218
1219 return $value;
1220
1221 /* Help:
1222 * First half of escaping for LIKE special characters % and _ before preparing for MySQL.
1223 * Use this only before wpdb::prepare() or esc_sql(). Reversing the order is very bad for security.
1224 *
1225 * Example Prepared Statement:
1226 *
1227 * $wild = '%';
1228 * $find = 'only 43% of planets';
1229 * $like = $wild . wpbm_esc_like( $find ) . $wild;
1230 * $sql = $wpdb->prepare( "SELECT * FROM $wpdb->posts WHERE post_content LIKE '%s'", $like );
1231 *
1232 * Example Escape Chain:
1233 *
1234 * $sql = esc_sql( wpbm_esc_like( $input ) );
1235 */
1236 }
1237
1238
1239 /** Escape string from SQL for the HTML form field
1240 *
1241 * @param string $value
1242 * @return string
1243 *
1244 * Used: esc_sql function.
1245 *
1246 * https://codex.wordpress.org/Function_Reference/esc_sql
1247 * Note: Be careful to use this function correctly. It will only escape values to be used in strings in the query.
1248 * That is, it only provides escaping for values that will be within quotes in the SQL (as in field = '{$escaped_value}').
1249 * If your value is not going to be within quotes, your code will still be vulnerable to SQL injection.
1250 * For example, this is vulnerable, because the escaped value is not surrounded by quotes in the SQL query:
1251 * ORDER BY {$escaped_value}. As such, this function does not escape unquoted numeric values, field names, or SQL keywords.
1252 *
1253 */
1254 function wpbm_clean_string_for_form( $value ){
1255
1256 global $wpdb;
1257
1258 $value_trimmed = trim( stripslashes( $value ) );
1259
1260 $esc_sql_value = esc_sql( $value_trimmed );
1261
1262 //$value = trim( $wpdb->prepare( "'%s'", $esc_sql_value ) , "'" );
1263
1264 $esc_sql_value = trim( stripslashes( $esc_sql_value ) );
1265
1266 return $esc_sql_value;
1267
1268 }
1269 // </editor-fold>
1270
1271
1272 // <editor-fold defaultstate="collapsed" desc=" U s e r s " >
1273 ////////////////////////////////////////////////////////////////////////////////
1274 // U s e r s
1275 ////////////////////////////////////////////////////////////////////////////////
1276
1277 /** Get ID of active user
1278 *
1279 * @return type
1280 */
1281 function get_wpbm_current_user_id() {
1282 $user = wp_get_current_user();
1283 return ( isset( $user->ID ) ? (int) $user->ID : 0 );
1284 }
1285
1286
1287 /**
1288 * Resolve a requested per-user settings target to the current user.
1289 *
1290 * Booking Manager's established AJAX payloads include a user ID. The value is
1291 * retained for request compatibility, but it must never authorize a write to
1292 * another user's preferences.
1293 *
1294 * @param mixed $requested_user_id User ID supplied by the request.
1295 *
1296 * @return int Current user ID when the request target matches; otherwise 0.
1297 */
1298 function wpbm_get_authorized_user_option_target_id( $requested_user_id ) {
1299 $current_user_id = get_wpbm_current_user_id();
1300
1301 if ( 0 === $current_user_id || ! is_scalar( $requested_user_id ) ) {
1302 return 0;
1303 }
1304
1305 $requested_user_id = absint( wp_unslash( (string) $requested_user_id ) );
1306
1307 return ( $current_user_id === $requested_user_id ) ? $current_user_id : 0;
1308 }
1309
1310
1311 /** Check if Current User have specific Role
1312 *
1313 * @return bool Whether the current user has the given capability.
1314 */
1315 function wpbm_is_current_user_have_this_role( $user_role ) {
1316
1317 if ( $user_role == 'administrator' ) $user_role = 'activate_plugins';
1318 if ( $user_role == 'editor' ) $user_role = 'publish_pages';
1319 if ( $user_role == 'author' ) $user_role = 'publish_posts';
1320 if ( $user_role == 'contributor' ) $user_role = 'edit_posts';
1321 if ( $user_role == 'subscriber') $user_role = 'read';
1322
1323 return current_user_can( $user_role );
1324 }
1325
1326
1327 function wpbm_get_user_ip() {
1328 return '---';
1329 }
1330 add_wpbm_filter( 'wpbm_get_user_ip', 'wpbm_get_user_ip' );
1331 // </editor-fold>
1332
1333
1334 // <editor-fold defaultstate="collapsed" desc=" Mesages for Admin panel " >
1335 ////////////////////////////////////////////////////////////////////////////////
1336 // Mesages for Admin panel
1337 ////////////////////////////////////////////////////////////////////////////////
1338
1339 function wpbm_show_fixed_message( $message, $time_to_show , $message_type = 'updated' , $notice_id = 0, $is_dismissible = false ) {
1340
1341 // Generate unique HTML ID for the message
1342 if ( $notice_id == 0 )
1343 $notice_id = intval( time() * wp_rand(10, 100) );
1344
1345 $notice_id = 'wpbm_system_notice_' . $notice_id;
1346
1347 $is_dismissible = false;
1348
1349 if (
1350 ( ( $is_dismissible ) && ( ! wpbm_section_is_dismissed( $notice_id ) ) )
1351 || ( ! $is_dismissible )
1352 // || true
1353 ){
1354
1355 ?><div id="<?php echo esc_attr($notice_id); ?>"
1356 class="wpbm_system_notice wpbm_is_dismissible wpbm_is_hideable <?php echo esc_attr( $message_type ); ?>"
1357 data-nonce="<?php echo esc_attr(wp_create_nonce( $nonce_name = $notice_id . '_wpbmnonce' )); ?>"
1358 data-user-id="<?php echo esc_attr(get_current_user_id()); ?>"
1359 ><?php
1360
1361 wpbm_x_dismiss_button();
1362
1363 echo wp_kses_post($message);
1364
1365 ?></div><?php
1366
1367 // Get the time of message showing
1368 $time_to_show = intval( $time_to_show ) * 1000;
1369
1370 if ( $time_to_show > 0 ) {
1371 ?> <script type="text/javascript">
1372 jQuery('#<?php echo esc_attr($notice_id); ?>').animate({opacity: 1},<?php echo esc_attr( $time_to_show ); ?>).fadeOut( 2000 );
1373 </script> <?php
1374 }
1375 }
1376 }
1377
1378
1379 /** Show Ajax message at the top of page
1380 *
1381 * @param type $message
1382 * @param type $time_to_show
1383 * @param type $is_error
1384 */
1385 function wpbm_show_ajax_message( $message, $time_to_show = 3000, $is_error = false ) {
1386
1387 // Recheck for any "lang" shortcodes for replacing to correct language
1388 $message = apply_wpbm_filter('wpbm_check_for_active_language', $message );
1389
1390 // Escape any JavaScript from message
1391 $notice = html_entity_decode( esc_js( $message ) ,ENT_QUOTES) ;
1392
1393 ?><script type="text/javascript">
1394 var my_message = '<?php echo esc_js( $notice ); ?>';
1395 wpbm_admin_show_message( my_message, '<?php echo ( $is_error ? 'error' : 'success' ); ?>', <?php echo esc_attr($time_to_show); ?> );
1396 </script><?php
1397 }
1398
1399
1400 /** Show "Saved Changes" message at the top of settings page.
1401 *
1402 */
1403 function wpbm_show_changes_saved_message() {
1404 wpbm_show_message ( __('Changes saved.', 'booking-manager'), 5 );
1405 }
1406
1407
1408 /** Show Message at Top of Admin Pages
1409 *
1410 * @param type $message - mesage to show
1411 * @param type $time_to_show - number of seconds to show, if 0 or skiped, then unlimited time.
1412 * @param type $message_type - Default: updated { updated | error | notice }
1413 */
1414 function wpbm_show_message ( $message, $time_to_show , $message_type = 'updated') {
1415
1416 // Generate unique HTML ID for the message
1417 $inner_message_id = intval( time() * wp_rand(10, 100) );
1418
1419 // Get formated HTML message
1420 $notice = wpbm_get_formated_message( $message, $message_type, $inner_message_id );
1421
1422 // Get the time of message showing
1423 $time_to_show = intval( $time_to_show ) * 1000;
1424
1425 // Show this Message
1426 ?> <script type="text/javascript">
1427 if ( jQuery('.wpbm_admin_message').length ) {
1428 jQuery('.wpbm_admin_message').append( '<?php
1429 // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
1430 echo ($notice);
1431 ?>' );
1432 <?php if ( $time_to_show > 0 ) { ?>
1433 jQuery('#wpbm_inner_message_<?php echo esc_attr($inner_message_id); ?>').animate({opacity: 1},<?php echo esc_attr($time_to_show); ?>).fadeOut( 2000 );
1434 <?php } ?>
1435 }
1436 </script> <?php
1437 }
1438
1439
1440 /** Escape and prepare message to show it
1441 *
1442 * @param type $message - message
1443 * @param type $message_type - Default: updated { updated | error | notice }
1444 * @param string $inner_message_id - ID of message DIV, can be skipped
1445 * @return string
1446 */
1447 function wpbm_get_formated_message ( $message, $message_type = 'updated', $inner_message_id = '') {
1448
1449
1450 // Recheck for any "lang" shortcodes for replacing to correct language
1451 $message = apply_wpbm_filter('wpbm_check_for_active_language', $message );
1452
1453 // Escape any JavaScript from message
1454 $notice = html_entity_decode( esc_js( $message ) ,ENT_QUOTES) ;
1455
1456 $notice .= '<a class="close tooltip_left" rel="tooltip" title="'. esc_js(__("Hide", 'booking-manager')). '" data-dismiss="alert" href="javascript:void(0)" onclick="javascript:jQuery(this).parent().hide();">&times;</a>';
1457
1458 if (! empty( $inner_message_id ))
1459 $inner_message_id = 'id="wpbm_inner_message_'. $inner_message_id .'"';
1460
1461 $notice = '<div '.$inner_message_id.' class="wpbm_inner_message '. $message_type . '">' . $notice . '</div>';
1462
1463 return $notice;
1464 }
1465
1466
1467 /** Show system info in settings page
1468 *
1469 * @param string $message ...
1470 * @param string $message_type 'info' | 'warning' | 'error'
1471 * @param string $title __('Important!' , 'booking-manager') | __('Note' , 'booking-manager')
1472 *
1473 * Exmaple: wpbm_show_message_in_settings( __( 'Nothing Found', 'booking-manager'), 'warning', __('Important!' , 'booking-manager') );
1474 */
1475 function wpbm_show_message_in_settings( $message, $message_type = 'info', $title = '' , $is_echo = true ) {
1476
1477 $message_content = '';
1478
1479 $message_content .= '<div class="clear"></div>';
1480
1481 $message_content .= '<div class="wpbm-settings-notice notice-' . $message_type . '" style="text-align:left;">';
1482
1483 if ( ! empty( $title ) )
1484 $message_content .= '<strong>' . esc_js( $title ) . '</strong> ';
1485
1486 $message_content .= html_entity_decode( esc_js( $message ) ,ENT_QUOTES) ;
1487
1488 $message_content .= '</div>';
1489
1490 $message_content .= '<div class="clear"></div>';
1491
1492 if ( $is_echo )
1493 echo wp_kses_post( $message_content );
1494 else
1495 return $message_content;
1496
1497 }
1498 // </editor-fold>
1499
1500
1501 // <editor-fold defaultstate="collapsed" desc=" Settings Meta Boxes " >
1502 ////////////////////////////////////////////////////////////////////////////////
1503 // Settings Meta Boxes
1504 ////////////////////////////////////////////////////////////////////////////////
1505 function wpbm_open_meta_box_section( $metabox_id, $title ) {
1506
1507 $my_close_open_win_id = $metabox_id . '_metabox';
1508 //FixIn: 2.0.16.1
1509 ?>
1510 <div class='meta-box'>
1511 <div
1512 id="<?php echo esc_attr($my_close_open_win_id); ?>"
1513 class="postbox <?php if ( '1' == get_user_option( 'wpbm_win_' . $my_close_open_win_id ) ) echo 'closed'; ?>"
1514 ><div class="postbox-header" style="display: flex;flex-flow: row nowrap;border-bottom: 1px solid #ccd0d4;"><?php //FixIn: 8.7.8.1 ?>
1515 <h3 class='hndle' style="flex: 1 1 auto;border: none;">
1516 <span><?php echo wp_kses_post( $title ); ?></span>
1517 </h3>
1518 <div title="<?php echo esc_attr(__('Click to toggle','booking-manager')); ?>"
1519 class="handlediv"
1520 onclick="javascript:wpbm_verify_window_opening(<?php echo esc_attr( get_wpbm_current_user_id() ); ?>, '<?php echo esc_attr($my_close_open_win_id); ?>');"
1521 ><br/></div>
1522 </div>
1523 <div class="inside">
1524 <?php
1525 }
1526
1527 function wpbm_close_meta_box_section() {
1528 ?>
1529 </div>
1530 </div>
1531 </div>
1532 <?php
1533 }
1534 // </editor-fold>
1535
1536
1537 // from Toolbar
1538 // <editor-fold defaultstate="collapsed" desc=" M o d a l s " >
1539 ////////////////////////////////////////////////////////////////////////////////
1540 // M o d a l s
1541 ////////////////////////////////////////////////////////////////////////////////
1542
1543 /** Start Loyouts - Modal Window structure */
1544 function wpbm_write_content_for_modals_start_here() {
1545
1546 ?><span id="wpbm_content_for_modals"></span><?php
1547 }
1548 add_wpbm_action( 'wpbm_write_content_for_modals', 'wpbm_write_content_for_modals_start_here');
1549 // </editor-fold>
1550
1551
1552 // <editor-fold defaultstate="collapsed" desc=" Inline JavaScript " >
1553 ////////////////////////////////////////////////////////////////////////////////
1554 // Inline J a v a S c r i p t to Footer page
1555 ////////////////////////////////////////////////////////////////////////////////
1556 /**
1557 * Queue JavaScript for later output at footer
1558 *
1559 * @param string $code
1560 */
1561 function wpbm_enqueue_js( $code ) {
1562 global $wpbm_queued_js;
1563
1564 if ( empty( $wpbm_queued_js ) ) {
1565 $wpbm_queued_js = '';
1566 }
1567
1568 $wpbm_queued_js .= "\n" . $code . "\n";
1569 }
1570
1571
1572 /**
1573 * Output any queued javascript code in the footer.
1574 */
1575 function wpbm_print_js() {
1576
1577 global $wpbm_queued_js;
1578
1579 if ( ! empty( $wpbm_queued_js ) ) {
1580
1581 echo "<!-- WPBM JavaScript -->\n<script type=\"text/javascript\">\njQuery(function($) {";
1582
1583 $wpbm_queued_js = wp_check_invalid_utf8( $wpbm_queued_js );
1584
1585 $wpbm_queued_js = wp_specialchars_decode( $wpbm_queued_js , ENT_COMPAT); // Converts double quotes '&quot;' => '"'
1586
1587 $wpbm_queued_js = preg_replace( '/&#(x)?0*(?(1)27|39);?/i', "'", $wpbm_queued_js );
1588 $wpbm_queued_js = str_replace( "\r", '', $wpbm_queued_js );
1589
1590 echo $wpbm_queued_js . "});\n</script>\n<!-- End WPBM JavaScript -->\n"; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
1591
1592 $wpbm_queued_js = '';
1593 unset( $wpbm_queued_js );
1594 }
1595 }
1596
1597 // </editor-fold>
1598
1599 // from Toolbar
1600 // <editor-fold defaultstate="collapsed" desc=" JS & CSS - Tooltips & Popover" >
1601 ////////////////////////////////////////////////////////////////////////////////
1602 // JS & CSS
1603 ////////////////////////////////////////////////////////////////////////////////
1604
1605 /** Load suport JavaScript for "Items" page*/
1606 function wpbm_js_for_items_page() {
1607
1608 $is_use_hints = get_wpbm_option( 'wpbm_is_use_hints_at_admin_panel' );
1609 if ( $is_use_hints == 'On' )
1610 wpbm_bs_javascript_tooltips(); // JS Tooltips
1611
1612 wpbm_bs_javascript_popover(); // JS Popover
1613
1614 //wpbm_datepicker_js(); // JS Datepicker
1615 wpbm_datepicker_css(); // CSS DatePicker
1616 }
1617
1618
1619 /** Datepicker activation JavaScript */
1620 function wpbm_datepicker_js() {
1621
1622 ?><script type="text/javascript">
1623 jQuery(document).ready( function(){
1624
1625 function applyCSStoDays( date ){
1626 return [true, 'date_available'];
1627 }
1628 jQuery('input.wpbm-filters-section-calendar').datepick(
1629 { beforeShowDay: applyCSStoDays,
1630 showOn: 'focus',
1631 multiSelect: 0,
1632 numberOfMonths: 1,
1633 stepMonths: 1,
1634 prevText: '&laquo;',
1635 nextText: '&raquo;',
1636 dateFormat: 'yy-mm-dd',
1637 changeMonth: false,
1638 changeYear: false,
1639 minDate: null,
1640 maxDate: null, //'1Y',
1641 showStatus: false,
1642 multiSeparator: ', ',
1643 closeAtTop: false,
1644 // firstDay:<?php //echo get_wpbm_option( 'wpbm_start_day_weeek' ); ?>,
1645 gotoCurrent: false,
1646 hideIfNoPrevNext:true,
1647 useThemeRoller :false,
1648 mandatory: true
1649 }
1650 );
1651 });
1652 </script><?php
1653 }
1654
1655
1656 /** Support CSS - datepick, etc... */
1657 function wpbm_datepicker_css(){
1658 ?>
1659 <style type="text/css">
1660 #datepick-div .datepick-header {
1661 width: 172px !important;
1662 }
1663 #datepick-div {
1664 -border-radius: 3px;
1665 -box-shadow: 0 0 2px #888888;
1666 -webkit-border-radius: 3px;
1667 -webkit-box-shadow: 0 0 2px #888888;
1668 -moz-border-radius: 3px;
1669 -moz-box-shadow: 0 0 2px #888888;
1670 width: 172px !important;
1671 }
1672 #datepick-div .datepick .datepick-days-cell a{
1673 font-size: 12px;
1674 }
1675 #datepick-div table.datepick tr td {
1676 border-top: 0 none !important;
1677 line-height: 24px;
1678 padding: 0 !important;
1679 width: 24px;
1680 }
1681 #datepick-div .datepick-control {
1682 font-size: 10px;
1683 text-align: center;
1684 }
1685 #datepick-div .datepick-one-month {
1686 height: auto;
1687 }
1688 </style>
1689 <?php
1690 }
1691
1692
1693 /** Sortable Table JavaScript */
1694 function wpbm_sortable_js() {
1695 ?>
1696 <script type="text/javascript">
1697 // Activate Sortable Functionality
1698 jQuery( document ).ready(function(){
1699
1700 jQuery('.wpbm_input_table tbody th').css('cursor','move');
1701
1702 jQuery('.wpbm_input_table tbody td.sort').css('cursor','move');
1703
1704 jQuery('.wpbm_input_table.sortable tbody').sortable({
1705 items:'tr',
1706 cursor:'move',
1707 axis:'y',
1708 scrollSensitivity:40,
1709 forcePlaceholderSize: true,
1710 helper: 'clone',
1711 opacity: 0.65,
1712 placeholder: '.wpbm_sortable_table .sort',
1713 start:function(event,ui){
1714 ui.item.css('background-color','#f6f6f6');
1715 },
1716 stop:function(event,ui){
1717 ui.item.removeAttr('style');
1718 }
1719 });
1720 });
1721 </script>
1722 <?php
1723
1724 }
1725 // </editor-fold>
1726
1727
1728 // <editor-fold defaultstate="collapsed" desc=" R e l o a d p a g e " >
1729 ////////////////////////////////////////////////////////////////////////////////
1730 // R e l o a d p a g e
1731 ////////////////////////////////////////////////////////////////////////////////
1732 /**
1733 * Reload page by using JavaScript
1734 *
1735 * @param string $url - URL of page to load
1736 */
1737 function wpbm_reload_page_by_js( $url ) {
1738
1739 $redir = html_entity_decode( esc_url( $url ) );
1740
1741 if ( ! empty( $redir ) ) {
1742 ?>
1743 <script type="text/javascript">
1744 window.location.href = '<?php echo esc_url($redir); ?>';
1745 </script>
1746 <?php
1747 }
1748 }
1749
1750
1751 /** Redirect browser to a specific page
1752 *
1753 * @param string $url - URL of page to redirect
1754 */
1755 function wpbm_redirect( $url ) {
1756
1757 $url = wpbm_make_link_absolute( $url );
1758
1759 $url = html_entity_decode( esc_url( $url ) );
1760
1761 echo '<script type="text/javascript">';
1762 echo 'window.location.href="'.esc_url($url).'";';
1763 echo '</script>';
1764 echo '<noscript>';
1765 echo '<meta http-equiv="refresh" content="0;url='.esc_url($url).'" />';
1766 echo '</noscript>';
1767 }
1768 // </editor-fold>
1769
1770
1771 // <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 " >
1772 /** Show P a g i n a t i o n
1773 *
1774 * @param int $summ_number_of_items - total number of items
1775 * @param int $active_page_num - number of activated page
1776 * @param int $num_items_per_page - number of items per page
1777 * @param array $only_these_parameters - array of keys to exclude from links
1778 * @param string $url_sufix - usefule for anchor to HTML section with specific ID, Example: '#my_section'
1779 */
1780 function wpbm_show_pagination( $summ_number_of_items, $active_page_num, $num_items_per_page , $only_these_parameters = false, $url_sufix = '' ) {
1781
1782 if ( empty( $num_items_per_page ) ) {
1783 $num_items_per_page = '10';
1784 }
1785
1786 $pages_number = ceil( $summ_number_of_items / $num_items_per_page );
1787 if ( $pages_number < 2 )
1788 return;
1789
1790 //Fix: 5.1.4 - Just in case we are having tooo much resources, then we need to show all resources - and its empty string
1791 // phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.NonceVerification.Missing, WordPress.Security.ValidatedSanitizedInput.InputNotValidated, WordPress.Security.ValidatedSanitizedInput.MissingUnslash, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.ValidatedSanitizedInput.MissingUnslash, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
1792 if ( ( isset($_REQUEST['wh_wpbm_type'] ) ) && ( strlen($_REQUEST['wh_wpbm_type']) > 1000 ) ) { $_REQUEST['wh_wpbm_type'] = ''; }
1793
1794 // First parameter will overwriten by $_GET['page'] parameter
1795 $bk_admin_url = wpbm_get_params_in_url( wpbm_get_master_url( false ), array('page_num'), $only_these_parameters );
1796
1797
1798 ?>
1799 <span class="wpdevelop wpbm-pagination">
1800 <div class="container-fluid">
1801 <div class="row">
1802 <div class="col-sm-12 text-center control-group0">
1803 <nav class="btn-toolbar">
1804 <div class="btn-group wpbm-no-margin" style="float:none;">
1805
1806 <?php if ( $pages_number > 1 ) { ?>
1807 <a class="button button-secondary <?php echo ( $active_page_num == 1 ) ? ' disabled' : ''; ?>"
1808 href="<?php echo esc_url($bk_admin_url); ?>&page_num=<?php if ($active_page_num == 1) { echo esc_attr( $active_page_num ); } else { echo esc_attr($active_page_num-1); } echo esc_attr( $url_sufix ); ?>">
1809 <?php esc_html_e('Prev', 'booking-manager'); ?>
1810 </a>
1811 <?php }
1812
1813 /** Number visible pages (links) that linked to active page, other pages skipped by "..." */
1814 $num_closed_steps = 3;
1815
1816 for ( $pg_num = 1; $pg_num <= $pages_number; $pg_num++ ) {
1817
1818 if ( ! (
1819 ( $pages_number > ( $num_closed_steps * 4) )
1820 && ( $pg_num > $num_closed_steps )
1821 && ( ( $pages_number - $pg_num + 1 ) > $num_closed_steps )
1822 && ( abs( $active_page_num - $pg_num ) > $num_closed_steps )
1823 ) ) {
1824 ?> <a class="button button-secondary <?php if ($pg_num == $active_page_num ) echo ' active'; ?>"
1825 href="<?php echo esc_attr( $bk_admin_url ); ?>&page_num=<?php echo esc_attr( $pg_num); echo esc_attr( $url_sufix); ?>">
1826 <?php echo esc_html($pg_num); ?>
1827 </a><?php
1828
1829 if ( ( $pages_number > ( $num_closed_steps * 4) )
1830 && ( ($pg_num+1) > $num_closed_steps )
1831 && ( ( $pages_number - ( $pg_num + 1 ) ) > $num_closed_steps )
1832 && ( abs($active_page_num - ( $pg_num + 1 ) ) > $num_closed_steps )
1833 ) {
1834 echo ' <a class="button button-secondary disabled" href="javascript:void(0);">...</a> ';
1835 }
1836 }
1837 }
1838
1839 if ( $pages_number > 1 ) { ?>
1840 <a class="button button-secondary <?php echo ( $active_page_num == $pages_number ) ? ' disabled' : ''; ?>"
1841 href="<?php echo esc_attr( $bk_admin_url ); ?>&page_num=<?php if ($active_page_num == $pages_number) { echo esc_attr( $active_page_num); } else { echo esc_attr($active_page_num+1); } echo esc_attr( $url_sufix); ?>">
1842 <?php esc_html_e('Next', 'booking-manager'); ?>
1843 </a>
1844 <?php } ?>
1845
1846 </div>
1847 </nav>
1848 </div>
1849 </div>
1850 </div>
1851 </span>
1852 <?php
1853 }
1854 // </editor-fold>
1855
1856
1857 // <editor-fold defaultstate="collapsed" desc=" D a t e s " >
1858 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1859 // Dates Format
1860 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1861
1862
1863 /** Get Formated Date & time
1864 *
1865 * @param string $date_sql - 2017-07-31 00:00:00 || 2017-07-31
1866 * @param string $date_format - Optional. - "m / d / Y, D H:i:s"
1867 * @param string $seperator - Optional. - " "
1868 * @return string - July 29, 2014 12:00 am
1869 */
1870 function wpbm_get_date_time_formatted( $date_sql, $date_format = false, $seperator = ' ', $skip_midnight_time = false ) {
1871
1872 $return_date = wpbm_get_date_formatted( $date_sql, $date_format );
1873
1874 $return_time = wpbm_get_time_formatted( $date_sql, $date_format, $skip_midnight_time );
1875 if ( ! empty( $return_time ) )
1876 $return_date .= $seperator . $return_time;
1877
1878 return $return_date;
1879 }
1880
1881
1882 /** Get Formated Date
1883 *
1884 * @param string $date_sql - 2017-07-31 00:00:00 || 2017-07-31
1885 * @param string $date_format - Optional. - "m / d / Y, D"
1886 * @param bool $skip_midnight_time - Default false - if 00:00:00 then return '';
1887 * @return string - July 29, 2014
1888 */
1889 function wpbm_get_date_formatted( $date_sql, $date_format = false ) {
1890
1891 if ( $date_format === false ) $date_format = get_wpbm_option( 'wpbm_date_format' );
1892 if ( empty( $date_format ) ) $date_format = "m / d / Y, D";
1893
1894 $formated_date = date_i18n( $date_format, strtotime( $date_sql ) );
1895
1896 return $formated_date;
1897 }
1898
1899
1900 /** Get Formated Date & time
1901 *
1902 * @param string $date_sql - 2017-07-31 00:00:00 || 2017-07-31
1903 * @param string $time_format - Optional. - "H:i:s"
1904 * @return string - 12:00 am
1905 */
1906 function wpbm_get_time_formatted( $date_sql, $time_format = false , $skip_midnight_time = false ) {
1907
1908 if ( ( $skip_midnight_time ) && ( '00:00:00' == substr( $date_sql, -8 ) ) )
1909 return '';
1910
1911 if ( $time_format === false ) $time_format = get_wpbm_option( 'wpbm_time_format' );
1912 if ( empty( $time_format ) ) $time_format = 'h:i a';
1913
1914 $formated_date = date_i18n( $time_format, strtotime( $date_sql ) );
1915
1916 return $formated_date;
1917 }
1918
1919
1920 /** Check if "current_day" is tomorrow from "next_day"
1921 *
1922 * @param string $current_day_sql_check : 2015-02-29 00:00:00
1923 * @param string $next_day_sql_check : 2015-02-30 00:00:00
1924 * @return boolean : true | false
1925 */
1926 function wpbm_is_next_day( $current_day_sql_check, $next_day_sql_check ) {
1927
1928 // Current day
1929 $current_day_unix = strtotime( $current_day_sql_check );
1930
1931 $current_day_midnight_sql = date_i18n( 'Y-m-d', $current_day_unix );
1932 $current_day_midnight_unix = strtotime( $current_day_midnight_sql );
1933
1934 $calc_next_day_unix = strtotime( '+1 day', $current_day_midnight_unix );
1935
1936 // Next day
1937 $next_day_unix = strtotime( $next_day_sql_check );
1938 $next_day_midnight_sql = date_i18n( 'Y-m-d', $next_day_unix );
1939 $next_day_midnight_unix = strtotime( $next_day_midnight_sql );
1940
1941
1942 if ( $calc_next_day_unix == $next_day_midnight_unix )
1943 return true;
1944 else
1945 return false;
1946 }
1947
1948 /** Check if "current_day" is same day of "other_day"
1949 *
1950 * @param string $current_day_sql_check : 2015-02-29 00:00:00
1951 * @param string $other_day_sql_check : 2015-02-30 00:00:00
1952 * @return boolean : true | false
1953 */
1954 function wpbm_is_this_same_day( $current_day_sql_check, $other_day_sql_check ) {
1955
1956 // Current day
1957 $current_day_unix = strtotime( $current_day_sql_check );
1958
1959 $current_day_midnight_sql = date_i18n( 'Y-m-d', $current_day_unix );
1960 $current_day_midnight_unix = strtotime( $current_day_midnight_sql );
1961
1962 // Other day
1963 $other_day_unix = strtotime( $other_day_sql_check );
1964 $other_day_midnight_sql = date_i18n( 'Y-m-d', $other_day_unix );
1965 $other_day_midnight_unix = strtotime( $other_day_midnight_sql );
1966
1967
1968 if ( $current_day_midnight_unix == $other_day_midnight_unix )
1969 return true;
1970 else
1971 return false;
1972 }
1973
1974
1975 /** Get days in short format view
1976 *
1977 * @param string $days Dates: 15.05.2015, 16.05.2015, 17.05.2015
1978 * @return string Dates in format: 15.05.2015 - 17.05.2015
1979 */
1980 function wpbm_get_dates_short_format( $dates_sql_csv ) { // $days - string with comma seperated dates
1981
1982 if ( empty( $dates_sql_csv ) )
1983 return '';
1984
1985 $days = explode( ',', $dates_sql_csv );
1986
1987 $previosday = false;
1988 $result_string = '';
1989 $last_show_day = '';
1990
1991 foreach ( $days as $day ) {
1992
1993 $is_fin_at_end = false;
1994
1995 if ( $previosday === false ) { // First Day
1996
1997 $result_string = wpbm_get_date_time_formatted( $day, false, ' ', true ); // echo format for first day
1998 $last_show_day = $day;
1999 $previosday = $day; // Set previos day for next loop
2000
2001 } else { // Not first day
2002
2003 if (
2004 wpbm_is_next_day( $previosday, $day )
2005 || wpbm_is_this_same_day( $previosday, $day )
2006 ) { // Check if $day next day from previous
2007
2008 $previosday = $day; // Set previos day for next loop
2009 $is_fin_at_end = true;
2010 } else {
2011 if ( $last_show_day !== $previosday ) { // check if previos day was show or no
2012 $result_string .= ' - ' . wpbm_get_date_time_formatted( $previosday, false, ' ', true ); // assign in needed format this day
2013 }
2014 $result_string .= ', ' . wpbm_get_date_time_formatted( $day, false, ' ', true ); // assign in needed format this day
2015 $previosday = $day; // Set previos day for next loop
2016 $last_show_day = $day;
2017 }
2018 }
2019
2020 }
2021
2022 if ( $is_fin_at_end ) {
2023 $result_string .= ' - ' . wpbm_get_date_time_formatted( $day, false, ' ', true );
2024 }
2025
2026 return $result_string;
2027 }
2028
2029 // </editor-fold>
2030