PluginProbe
Booking Calendar / 11.8.1
Booking Calendar v11.8.1
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 11.8.1, at core/wpbc_functions.php

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