PluginProbe
Booking Calendar / 11.7
Booking Calendar v11.7
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 10.11.4 10.12.0 All 200 releases
booking / core / wpbc_functions.php

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

1,816 lines 65.6 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 && defined( 'WPBC_ENABLE_11_6_CATALOG_V2' )
561 && WPBC_ENABLE_11_6_CATALOG_V2
562 )
563 )
564 ) {
565 return true;
566 }
567
568 return false;
569 }
570
571
572 /**
573 * Can I load scripts on this page for 'shortcode_config'
574 *
575 * @return bool
576 */
577 function wpbc_can_i_load_on_this_page__shortcode_config() {
578
579 if (
580 wpbc_can_i_load_on__edit_new_post_page()
581 || (
582 wpbc_can_i_load_on__resources_page()
583 && ( ! wpbc_can_i_load_on__searchable_resources_page() )
584 )
585 || wpbc_is_setup_wizard_page()
586 || wpbc_is_builder_booking_form_page()
587 // || wpbc_is_bookings_page() // FixIn: 10.6.6.2.
588 ){
589 return true;
590 } else {
591 return false;
592 }
593 }
594
595 /**
596 * Can I load scripts on this page? Loaded only at ../admin.php?page=wpbc-resources&tab=searchable_resources
597 *
598 * @return bool
599 */
600 function wpbc_can_i_load_on_this_page__modal_search_options() {
601
602 if ( wpbc_can_i_load_on__searchable_resources_page() ){
603 return true;
604 } else {
605 return false;
606 }
607 }
608
609 // </editor-fold>
610
611
612 // <editor-fold defaultstate="collapsed" desc=" == Footer == " >
613
614 function wpbc_show_booking_footer(){
615
616 $wpdev_copyright_adminpanel = get_bk_option( 'booking_wpdev_copyright_adminpanel' ); // check
617
618 $message = '';
619
620
621
622 if ( ( 'Off' !== $wpdev_copyright_adminpanel ) && ( ! wpbc_is_this_demo() ) ) {
623
624
625 /* translators: 1: ... */
626 $message .= sprintf( __( 'If you like %1$s please leave us a %2$s rating. A huge thank you in advance!', 'booking' )
627 , '<strong>Booking Calendar</strong> ' . esc_attr( WP_BK_VERSION_NUM )
628 , '<a href="https://wordpress.org/support/plugin/booking/reviews/#new-post" target="_blank" title="' . esc_attr__( 'Thanks :)', 'booking' ) . '">'
629 . '&#9733;&#9733;&#9733;&#9733;&#9733;'
630 . '</a>'
631 );
632 }
633
634
635 if ( ! empty( $message ) ) {
636
637 // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
638 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>';
639
640 ?>
641 <script type="text/javascript">
642 jQuery(document).ready(function () {
643 jQuery('#wpfooter').append(jQuery('#wpbc-footer'));
644 });
645 </script>
646 <?php
647 }
648 }
649
650 // </editor-fold>
651
652
653 // <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 == " >
654
655 /**
656 * Show P a g i n a t i o n
657 *
658 * @param int $summ_number_of_items - total number of items
659 * @param int $active_page_num - number of activated page
660 * @param int $num_items_per_page - number of items per page
661 * @param array $only_these_parameters - array of keys to exclude from links
662 * @param string $url_sufix - usefule for anchor to HTML section with specific ID, Example: '#my_section'
663 */
664 function wpbc_show_pagination( $summ_number_of_items, $active_page_num, $num_items_per_page , $only_these_parameters = false, $url_sufix = '' ) {
665
666 if ( empty( $num_items_per_page ) ) {
667 $num_items_per_page = '10';
668 }
669
670 $pages_number = ceil( $summ_number_of_items / $num_items_per_page );
671 if ( $pages_number < 2 )
672 return;
673
674 //Fix: 5.1.4 - Just in case we are having tooo much resources, then we need to show all resources - and its empty string
675 // phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.NonceVerification.Missing, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
676 if ( ( isset( $_REQUEST['wh_booking_type'] ) ) && ( strlen( wp_unslash( $_REQUEST['wh_booking_type'] ) ) > 1000 ) ) {
677 $_REQUEST['wh_booking_type'] = '';
678 }
679
680 // First parameter will overwriten by $_GET['page'] parameter
681 $bk_admin_url = wpbc_get_params_in_url( wpbc_get_bookings_url( false, false ), array('page_num'), $only_these_parameters );
682
683
684 ?>
685 <span class="wpdevelop wpbc-pagination">
686 <div class="container-fluid">
687 <div class="row">
688 <div class="col-sm-12 text-center control-group0">
689 <nav class="btn-toolbar">
690 <div class="btn-group wpbc-no-margin" style="float:none;">
691
692 <?php
693 if ( $pages_number > 1 ) { ?>
694 <a class="button button-secondary <?php
695 echo ( $active_page_num == 1 ) ? ' disabled' : ''; ?>"
696 href="<?php
697 echo esc_url( $bk_admin_url ); ?>&page_num=<?php
698 if ( $active_page_num == 1 ) {
699 echo esc_attr( $active_page_num );
700 } else {
701 echo esc_attr( $active_page_num - 1 );
702 }
703 echo esc_attr( $url_sufix );
704 ?>">
705 <?php
706 esc_html_e( 'Prev', 'booking' ); ?>
707 </a>
708 <?php
709 }
710
711 /** Number visible pages (links) that linked to active page, other pages skipped by "..." */
712 $num_closed_steps = 3;
713
714 for ( $pg_num = 1; $pg_num <= $pages_number; $pg_num++ ) {
715
716 if ( ! (
717 ( $pages_number > ( $num_closed_steps * 4) )
718 && ( $pg_num > $num_closed_steps )
719 && ( ( $pages_number - $pg_num + 1 ) > $num_closed_steps )
720 && ( abs( $active_page_num - $pg_num ) > $num_closed_steps )
721 ) ) {
722 ?> <a class="button button-secondary <?php if ($pg_num == $active_page_num ) echo ' active'; ?>"
723 href="<?php echo esc_url( $bk_admin_url ); ?>&page_num=<?php echo esc_attr( $pg_num );
724 // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
725 echo $url_sufix; ?>">
726 <?php echo wp_kses_post( $pg_num ); ?>
727 </a><?php
728
729 if ( ( $pages_number > ( $num_closed_steps * 4) )
730 && ( ($pg_num+1) > $num_closed_steps )
731 && ( ( $pages_number - ( $pg_num + 1 ) ) > $num_closed_steps )
732 && ( abs($active_page_num - ( $pg_num + 1 ) ) > $num_closed_steps )
733 ) {
734 echo ' <a class="button button-secondary disabled" href="javascript:void(0);">...</a> ';
735 }
736 }
737 }
738
739 if ( $pages_number > 1 ) { ?>
740 <a class="button button-secondary <?php
741 echo ( $active_page_num == $pages_number ) ? ' disabled' : ''; ?>"
742 href="<?php
743 echo esc_url( $bk_admin_url ); ?>&page_num=<?php
744 if ( $active_page_num == $pages_number ) {
745 echo esc_attr( $active_page_num );
746 } else {
747 echo esc_attr( $active_page_num + 1 );
748 }
749 // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
750 echo $url_sufix; ?>">
751 <?php
752 esc_html_e( 'Next', 'booking' ); ?>
753 </a>
754 <?php
755 }
756 ?>
757
758 </div>
759 </nav>
760 </div>
761 </div>
762 </div>
763 </span>
764 <?php
765 }
766
767 // </editor-fold>
768
769
770 // <editor-fold defaultstate="collapsed" desc=" == Number of New Bookings == " >
771
772 /**
773 * Reset Cache for getting Number of new bookings. After this operation, system will get number of new bookings from the DB.
774 *
775 * @return void
776 */
777 function wpbc_booking_cache__new_bookings__reset(){
778 update_bk_option( 'booking_cache__new_bookings__saved_date', '' );
779 }
780 add_action( 'wpbc_track_new_booking', 'wpbc_booking_cache__new_bookings__reset' );
781 add_action( 'wpbc_set_booking_pending', 'wpbc_booking_cache__new_bookings__reset' );
782 add_action( 'wpbc_set_booking_approved', 'wpbc_booking_cache__new_bookings__reset' );
783 add_action( 'wpbc_move_booking_to_trash', 'wpbc_booking_cache__new_bookings__reset' );
784 add_action( 'wpbc_restore_booking_from_trash', 'wpbc_booking_cache__new_bookings__reset' );
785 add_action( 'wpbc_delete_booking_completely', 'wpbc_booking_cache__new_bookings__reset' );
786 add_action( 'wpbc_set_booking_as_read', 'wpbc_booking_cache__new_bookings__reset' );
787 add_action( 'wpbc_set_booking_as_unread', 'wpbc_booking_cache__new_bookings__reset' );
788
789
790 /**
791 * Get number of new bookings
792 * @return false|int|mixed|null
793 */
794 function wpbc_db_get_number_new_bookings() {
795
796 $new_bookings__number = get_bk_option( 'booking_cache__new_bookings__number' );
797 $new_bookings__saved_date = get_bk_option( 'booking_cache__new_bookings__saved_date' );
798
799 $nowdate_str_ymdhis = gmdate( 'Y-m-d H:i:s', strtotime( 'now' ) );
800
801 if ( ! empty( $new_bookings__saved_date ) ) {
802
803 $is_expired = ( strtotime( $new_bookings__saved_date ) <= strtotime( '-10 minutes', strtotime( $nowdate_str_ymdhis ) ) );
804
805 if ( ! $is_expired ) {
806 return $new_bookings__number;
807 }
808 }
809
810 global $wpdb;
811
812 $trash_bookings = ' AND bk.trash != 1 '; // FixIn: 6.1.1.10 - check also below usage of {$trash_bookings} .
813 $sql_req = "SELECT bk.booking_id FROM {$wpdb->prefix}booking as bk WHERE bk.is_new = 1 {$trash_bookings} ";
814
815 $sql_req = apply_bk_filter( 'get_sql_for_checking_new_bookings', $sql_req );
816 $sql_req = apply_bk_filter( 'get_sql_for_checking_new_bookings_multiuser', $sql_req );
817 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.NotPrepared, PluginCheck.Security.DirectDB.UnescapedDBParameter
818 $bookings = $wpdb->get_results( $sql_req );
819 $bookings_count = count( $bookings );
820
821 update_bk_option( 'booking_cache__new_bookings__number', $bookings_count );
822 update_bk_option( 'booking_cache__new_bookings__saved_date', $nowdate_str_ymdhis );
823
824 return $bookings_count;
825 }
826
827
828 /**
829 * Update 'is_new' status of bookings in Database
830 *
831 * @param $id_of_new_bookings inr or comma seperated ID of bookings. Example: '1' | '3,5,7,9'
832 * @param $is_new '0' | '1'
833 * @param $user_id 'user_id'
834 *
835 */
836 function wpbc_db_update_number_new_bookings( $id_of_new_bookings, $is_new = '0', $user_id = 1 ) {
837
838 global $wpdb;
839
840 if ( count( $id_of_new_bookings ) > 0 ) {
841
842 $id_of_new_bookings = implode( ',', $id_of_new_bookings );
843 $id_of_new_bookings = wpbc_clean_like_string_for_db( $id_of_new_bookings );
844
845 // FixIn: 10.12.1.5.
846 if ( 'all' === $id_of_new_bookings ) {
847 $update_sql = "UPDATE {$wpdb->prefix}booking SET is_new = {$is_new} WHERE is_new != {$is_new} "; // FixIn: 8.2.1.18.
848
849 $update_sql = apply_bk_filter( 'update_sql_for_checking_new_bookings', $update_sql, 0, $user_id );
850 } else {
851 $update_sql = "UPDATE {$wpdb->prefix}booking SET is_new = {$is_new} WHERE booking_id IN ( {$id_of_new_bookings} ) ";
852 }
853
854 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.NotPrepared, PluginCheck.Security.DirectDB.UnescapedDBParameter
855 if ( false === $wpdb->query( $update_sql ) ) {
856 debuge_error( 'Error during updating status of bookings at DB', __FILE__, __LINE__ );
857 die();
858 }
859 }
860 }
861
862 // </editor-fold>
863
864
865 // <editor-fold defaultstate="collapsed" desc=" == User ID | Role - functions == " >
866
867 /**
868 * Check if Current User have specific Role
869 *
870 * @return bool Whether the current user has the given capability.
871 */
872 function wpbc_is_current_user_have_this_role( $user_role ) {
873
874 if ( $user_role == 'administrator' ) $user_role = 'activate_plugins';
875 if ( $user_role == 'editor' ) $user_role = 'publish_pages';
876 if ( $user_role == 'author' ) $user_role = 'publish_posts';
877 if ( $user_role == 'contributor' ) $user_role = 'edit_posts';
878 if ( $user_role == 'subscriber') $user_role = 'read';
879
880 return current_user_can( $user_role );
881 }
882
883
884 /**
885 * Get Current ID of user or get user ID of Forced log in user in Booking Calendar MultiUser version.
886 *
887 * @return int
888 */
889 function wpbc_get_current_user_id() { // FixIn: 9.2.4.1.
890
891 if ( function_exists( 'wpbc_mu__wp_get_current_user' ) ) {
892 $user = wpbc_mu__wp_get_current_user();
893 $user_bk_id = $user->ID;
894 } else {
895 $user_bk_id = get_current_user_id();
896 }
897
898 return $user_bk_id;
899 }
900
901
902 /**
903 * Get Current User Object or get User object of Forced log in user in Booking Calendar MultiUser version.
904 *
905 * @return stdClass|WP_User|null
906 */
907 function wpbc_get_current_user() { // FixIn: 9.2.4.1.
908
909 if ( function_exists( 'wpbc_mu__wp_get_current_user' ) ) {
910 $user = wpbc_mu__wp_get_current_user();
911 } else {
912 $user = wp_get_current_user();
913 }
914
915 return $user;
916 }
917
918 // </editor-fold>
919
920
921 // <editor-fold defaultstate="collapsed" desc=" == Messages for Admin panel == " >
922
923
924 /**
925 * Show "Saved Changes" message at the top of settings page.
926 *
927 */
928 function wpbc_show_changes_saved_message() {
929 wpbc_show_message ( __('Changes saved.','booking'), 5 );
930 }
931
932
933 /**
934 * Show Message at Top of Admin Pages
935 *
936 * @param type $message - mesage to show
937 * @param type $time_to_show - number of seconds to show, if 0 or skiped, then unlimited time.
938 * @param type $message_type - Default: updated { updated | error | notice }
939 */
940 function wpbc_show_message ( $message, $time_to_show , $message_type = 'updated') {
941
942 // Generate unique HTML ID for the message
943 $inner_message_id = intval( time() * wp_rand(10, 100) );
944
945 // Get formated HTML message
946 $notice = wpbc_get_formated_message( $message, $message_type, $inner_message_id );
947
948 // Get the time of message showing
949 $time_to_show = intval( $time_to_show ) * 1000;
950
951 // Show this Message
952 ?> <script type="text/javascript">
953 if ( jQuery('.wpbc_admin_message').length ) {
954 jQuery('.wpbc_admin_message').append( '<?php
955 // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
956 echo $notice; ?>' );
957 <?php if ( $time_to_show > 0 ) { ?>
958 jQuery('#wpbc_inner_message_<?php echo esc_attr( $inner_message_id ); ?>').animate({opacity: 1},<?php echo esc_attr( $time_to_show ); ?>).fadeOut( 2000 );
959 <?php } ?>
960 }
961 </script> <?php
962 }
963
964
965 /**
966 * Escape and prepare message to show it
967 *
968 * @param type $message - message
969 * @param type $message_type - Default: updated { updated | error | notice }
970 * @param string $inner_message_id - ID of message DIV, can be skipped
971 * @return string
972 */
973 function wpbc_get_formated_message ( $message, $message_type = 'updated', $inner_message_id = '') {
974
975
976 // Recheck for any "lang" shortcodes for replacing to correct language
977 $message = wpbc_lang( $message );
978
979 // Escape any JavaScript from message
980 $notice = html_entity_decode( esc_js( $message ) ,ENT_QUOTES) ;
981
982 $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>';
983
984 if (! empty( $inner_message_id ))
985 $inner_message_id = 'id="wpbc_inner_message_'. $inner_message_id .'"';
986
987 $notice = '<div '.$inner_message_id.' class="wpbc_inner_message '. $message_type . '">' . $notice . '</div>';
988
989 return $notice;
990 }
991
992
993 /**
994 * Show system info in settings page
995 *
996 * @param string $message ...
997 * @param string $message_type 'info' | 'warning' | 'error'
998 * @param string $title __('Important!' ,'booking') | __('Note' ,'booking')
999 *
1000 * Exmaple: wpbc_show_message_in_settings( __( 'Nothing Found', 'booking' ), 'warning', __('Important!' ,'booking') );
1001 */
1002 function wpbc_show_message_in_settings( $message, $message_type = 'info', $title = '' , $is_echo = true ) {
1003
1004 $message_content = '';
1005
1006 $message_content .= '<div class="clear"></div>';
1007
1008 $message_content .= '<div class="wpbc-settings-notice notice-' . $message_type . '" style="text-align:left;">';
1009
1010 if ( ! empty( $title ) )
1011 $message_content .= '<strong>' . esc_js( $title ) . '</strong> ';
1012
1013 $message_content .= html_entity_decode( esc_js( $message ) ,ENT_QUOTES) ;
1014
1015 $message_content .= '</div>';
1016
1017 $message_content .= '<div class="clear"></div>';
1018
1019 if ( $is_echo ) {
1020 // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
1021 echo $message_content;
1022 } else {
1023 return $message_content;
1024 }
1025
1026 }
1027
1028 // </editor-fold>
1029
1030
1031 // <editor-fold defaultstate="collapsed" desc=" == Meta Boxes - Open/Close == " >
1032
1033 /**
1034 * Meta box section open tag
1035 *
1036 * @param string $metabox_id HTML ID of section
1037 * @param string $title Title in section
1038 * @param array $params [
1039 '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
1040 'is_show_minimize' => true // Default true - is show minimize button at top right section
1041 ]
1042 *
1043 * @return void
1044 */
1045 function wpbc_open_meta_box_section( $metabox_id, $title, $params = array() ) {
1046
1047 $defaults = array(
1048 'is_section_visible_after_load' => true,
1049 'is_show_minimize' => true,
1050 'dismiss_button' => '',
1051 'css_class' => 'postbox'
1052 );
1053 $params = wp_parse_args( $params, $defaults );
1054
1055 $my_close_open_win_id = $metabox_id . '_metabox';
1056
1057 ?>
1058 <div class='meta-box'>
1059 <div id="<?php echo esc_attr( $my_close_open_win_id ); ?>"
1060 class="<?php echo esc_attr( $params['css_class'] ); ?> <?php
1061 if ( $params['is_show_minimize'] ) {
1062 if ( '1' == get_user_option( 'booking_win_' . $my_close_open_win_id ) ) {
1063 echo 'closed';
1064 }
1065 }
1066 ?>"
1067 style="<?php
1068
1069 $force_visible = false;
1070
1071 // phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.NonceVerification.Missing
1072 $do_expand = ( ( isset( $_REQUEST['do_expand'] ) ) ? sanitize_text_field( wp_unslash( $_REQUEST['do_expand'] ) ) : '' );
1073
1074 if ( $my_close_open_win_id === $do_expand ) {
1075 $force_visible = true;
1076 }
1077
1078 if ( ( ! $params['is_section_visible_after_load'] ) && ( ! $force_visible ) ) {
1079 echo 'display:none';
1080 }
1081 ?>"
1082 ><div class="postbox-header" style="display: flex;flex-flow: row nowrap;border-bottom: 1px solid #ccd0d4;">
1083 <h3 class='hndle' style="flex: 1 1 auto;border: none;">
1084 <span><?php
1085 // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
1086 echo $title;
1087 ?></span>
1088 <?php
1089 // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
1090 echo $params['dismiss_button'];
1091 ?>
1092 </h3>
1093 <?php if ( $params['is_show_minimize'] ) { ?>
1094 <div title="<?php esc_attr_e('Click to toggle','booking'); ?>" class="handlediv"
1095 onclick="javascript:wpbc_verify_window_opening(<?php echo esc_attr( wpbc_get_current_user_id() ); ?>, '<?php echo esc_attr( $my_close_open_win_id ); ?>');"
1096 ><br/></div>
1097 <?php } ?>
1098 </div>
1099 <div class="inside">
1100 <?php
1101 }
1102
1103
1104 function wpbc_close_meta_box_section() {
1105 ?>
1106 </div>
1107 </div>
1108 </div>
1109 <?php
1110 }
1111
1112 // </editor-fold>
1113
1114
1115 // <editor-fold defaultstate="collapsed" desc=" == Inline JavaScript to Footer page == " >
1116
1117 /**
1118 * Queue JavaScript for later output at footer
1119 *
1120 * @param string $code
1121 */
1122 function wpbc_enqueue_js( $code ) {
1123 global $wpbc_queued_js;
1124
1125 if ( empty( $wpbc_queued_js ) ) {
1126 $wpbc_queued_js = '';
1127 }
1128
1129 $wpbc_queued_js .= "\n" . $code . "\n";
1130 }
1131
1132
1133 /**
1134 * Output any queued javascript code in the footer.
1135 */
1136 function wpbc_print_js() {
1137
1138 global $wpbc_queued_js;
1139
1140 if ( ! empty( $wpbc_queued_js ) ) {
1141
1142 $wpbc_queued_js = wp_check_invalid_utf8( $wpbc_queued_js );
1143
1144 $wpbc_queued_js = wp_specialchars_decode( $wpbc_queued_js, ENT_COMPAT ); // Converts double quotes '&quot;' => '"'.
1145
1146 $wpbc_queued_js = preg_replace( '/&#(x)?0*(?(1)27|39);?/i', "'", $wpbc_queued_js );
1147 $wpbc_queued_js = str_replace( "\r", '', $wpbc_queued_js );
1148
1149 // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
1150 echo "<!-- WPBC JavaScript -->\n<script type=\"text/javascript\">\njQuery(function($) {" . $wpbc_queued_js . "});\n</script>\n<!-- End WPBC JavaScript -->\n";
1151
1152 $wpbc_queued_js = '';
1153 unset( $wpbc_queued_js );
1154 }
1155 }
1156
1157 // </editor-fold>
1158
1159
1160 // <editor-fold defaultstate="collapsed" desc=" == Support functions for MU version == " >
1161
1162 /**
1163 * Set active User Environment in MultiUser version, depend from owner of booking resource
1164 *
1165 * @param int $previous_active_user (default=-1) - blank parameter
1166 * @param int $bktype - booking resource ID for checking
1167 * @return int - ID of Previous Active User
1168 *
1169 * Usage:
1170 $previous_active_user = apply_bk_filter('wpbc_mu_set_environment_for_owner_of_resource', -1, $bktype );
1171
1172 */
1173 function wpbc_mu_set_environment_for_owner_of_resource( $previous_active_user = -1, $bktype = 1 ) {
1174
1175 if ( class_exists( 'wpdev_bk_multiuser' ) ) {
1176 // Get the owner of this booking resource
1177 $user_bk_id = apply_bk_filter( 'get_user_of_this_bk_resource', false, $bktype );
1178
1179 $user = wpbc_get_current_user();
1180
1181 // Get possible other active user settings
1182 $previous_active_user = apply_bk_filter( 'get_client_side_active_params_of_user' );
1183
1184 // Set active user of that specific booking resource
1185 make_bk_action( 'check_multiuser_params_for_client_side_by_user_id', $user_bk_id );
1186 }
1187
1188 return $previous_active_user;
1189 }
1190 add_bk_filter('wpbc_mu_set_environment_for_owner_of_resource', 'wpbc_mu_set_environment_for_owner_of_resource');
1191
1192
1193 /**
1194 * Set environment for this user in MU version
1195 *
1196 * @param int $previous_active_user - ID of user
1197 * Usage:
1198 make_bk_action('wpbc_mu_set_environment_for_user', $previous_active_user );
1199
1200 */
1201 function wpbc_mu_set_environment_for_user( $previous_active_user ) {
1202
1203 if ( $previous_active_user !== -1 ) {
1204
1205 // Reactivate the previous active user
1206 make_bk_action('check_multiuser_params_for_client_side_by_user_id', $previous_active_user );
1207 }
1208 }
1209 add_bk_action('wpbc_mu_set_environment_for_user', 'wpbc_mu_set_environment_for_user');
1210
1211
1212 /**
1213 * Check if we have simulated user login in Booking Calendar MultiUser version
1214 * return user ID of regular simulated user or 0 if not simulated
1215 * @return int
1216 */
1217 function wpbc_mu__is_simulated_login_as_user(){
1218 if ( class_exists( 'wpdev_bk_multiuser' ) ) {
1219
1220 $real_current_user_id = get_current_user_id(); // Is current user suer booking admin and if this user was simulated log in
1221 $is_user_super_admin = apply_bk_filter( 'is_user_super_admin', $real_current_user_id );
1222 if ( $is_user_super_admin ) {
1223
1224 $simulate_user_id = intval( get_option( 'booking_simulate_login_as_user' ) ); // Is user was simulated log in
1225
1226 if ( ( ! empty( $simulate_user_id ) ) && ( $simulate_user_id > 0 ) ) {
1227 return $simulate_user_id;
1228 }
1229 }
1230 }
1231 return 0;
1232 }
1233 // </editor-fold>
1234
1235
1236 // <editor-fold defaultstate="collapsed" desc=" == Currency functions (>=BS) == " >
1237
1238 /**
1239 * Format booking cost with a currency symbol.
1240 * In MultiUser version also checking about specific currency that belong to specific WordPress user.
1241 * This checking based on belonging specific booking resource to specific user.
1242 *
1243 * @param float $cost
1244 * @param int $booking_resource_id
1245 * @return string - $cost_to_show_with_currency
1246 */
1247 function wpbc_get_cost_with_currency_for_user( $cost, $booking_resource_id = 0 ){
1248
1249 if ( ( $cost === '' ) || ( ! class_exists( 'wpdev_bk_biz_s' ) ) ) {
1250 return '';
1251 }
1252
1253 if ( ! empty( $booking_resource_id ) ) {
1254 $previous_active_user = apply_bk_filter( 'wpbc_mu_set_environment_for_owner_of_resource', - 1, $booking_resource_id );
1255 } // MU
1256
1257 $cost_to_show_with_currency = wpbc_cost_show( $cost, array( 'currency' => wpbc_get_currency() ) );
1258
1259 if ( ! empty( $booking_resource_id ) ) {
1260 make_bk_action( 'wpbc_mu_set_environment_for_user', $previous_active_user );
1261 } // MU
1262
1263 return $cost_to_show_with_currency;
1264 }
1265
1266
1267 /**
1268 * Get currency Symbol.
1269 * In MultiUser version also checking about specific currency that belong to specific WordPress user.
1270 * This checking based on belonging specific booking resource to specific user.
1271 *
1272 * @param int $booking_resource_id - ID of specific booking resource
1273 * @return string - currency symbol
1274 */
1275 function wpbc_get_currency_symbol_for_user( $booking_resource_id = 0 ){
1276
1277 if ( ! class_exists( 'wpdev_bk_biz_s' ) ) {
1278 return '';
1279 }
1280
1281 if ( ! empty( $booking_resource_id ) ) {
1282 $previous_active_user = apply_bk_filter( 'wpbc_mu_set_environment_for_owner_of_resource', - 1, $booking_resource_id );
1283 } // MU
1284
1285 $currency_symbol = wpbc_get_currency_symbol();
1286
1287 if ( ! empty( $booking_resource_id ) ) {
1288 make_bk_action( 'wpbc_mu_set_environment_for_user', $previous_active_user );
1289 } // MU
1290
1291 return $currency_symbol;
1292 }
1293
1294 /**
1295 * Get Cost per period: DAY / NIGHT / FIXED / HOUR
1296 * In MultiUser version This checking based on belonging specific booking resource to specific user.
1297 *
1298 * @param int $booking_resource_id - ID of specific booking resource
1299 * @return string - cost per period
1300 */
1301 function wpbc_get_cost_per_period_for_user( $booking_resource_id = 0 ){ // FixIn: 10.0.0.14.
1302
1303 if ( ! class_exists( 'wpdev_bk_biz_s' ) ) {
1304 return '';
1305 }
1306
1307 if ( ! empty( $booking_resource_id ) ) {
1308 $previous_active_user = apply_bk_filter( 'wpbc_mu_set_environment_for_owner_of_resource', - 1, $booking_resource_id );
1309 } // MU
1310
1311 $cost_period = get_bk_option( 'booking_paypal_price_period' );
1312
1313 if ( ! empty( $booking_resource_id ) ) {
1314 make_bk_action( 'wpbc_mu_set_environment_for_user', $previous_active_user );
1315 } // MU
1316
1317 return $cost_period;
1318 }
1319 // </editor-fold>
1320
1321
1322 // <editor-fold defaultstate="collapsed" desc=" == Approve | Pending functions == " >
1323
1324 /**
1325 * Check is this booking approved -- get booking dates in DB and check status
1326 *
1327 * @param $booking_id
1328 *
1329 * @return bool
1330 */
1331 function wpbc_is_booking_approved( $booking_id ) {
1332 // FixIn: 8.1.2.8.
1333
1334 $is_booking_approved = false;
1335
1336 global $wpdb;
1337
1338 $sql = $wpdb->prepare( "SELECT DISTINCT approved FROM {$wpdb->prefix}bookingdates WHERE booking_id = %d ORDER BY booking_date", $booking_id );
1339 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.NotPrepared, PluginCheck.Security.DirectDB.UnescapedDBParameter
1340 $dates_result = $wpdb->get_results( $sql );
1341
1342 foreach ( $dates_result as $my_date ) {
1343
1344 if ( 1 === intval( $my_date->approved ) ) {
1345 $is_booking_approved = true; // FixIn: 8.3.1.2.
1346 }
1347 }
1348
1349 return $is_booking_approved;
1350 }
1351
1352
1353 /**
1354 * Approve booking in DB (update booking dates in DB like approved = '1')
1355 *
1356 * @param $booking_id int | CSD e.g. 100 | '1,5,10'
1357 *
1358 * @return bool
1359 */
1360 function wpbc_db__booking_approve( $booking_id ) {
1361
1362 $booking_id = wpbc_clean_digit_or_csd( $booking_id ); // Check parameter if it number or comma separated list of numbers.
1363
1364 global $wpdb;
1365
1366 $update_sql = "UPDATE {$wpdb->prefix}bookingdates SET approved = '1' WHERE booking_id IN ({$booking_id});";
1367
1368 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.NotPrepared, PluginCheck.Security.DirectDB.UnescapedDBParameter
1369 if ( false === $wpdb->query( $update_sql ) ) {
1370 return false;
1371 }
1372
1373 // In case if the booking was in Trash, then restore it.
1374 // FixIn: 10.8.1.1.
1375
1376 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.PreparedSQL.InterpolatedNotPrepared, PluginCheck.Security.DirectDB.UnescapedDBParameter
1377 if ( false === $wpdb->query( "UPDATE {$wpdb->prefix}booking SET trash = 0 WHERE booking_id IN ({$booking_id})" ) ) {
1378 return false;
1379 }
1380
1381 return true;
1382 }
1383
1384
1385 /**
1386 * Approve specific booking and send email about this.
1387 *
1388 * @param int $booking_id - ID of booking
1389 * @param string $email_reason
1390 */
1391 function wpbc_auto_approve_booking( $booking_id, $email_reason = '' ) {
1392
1393 $booking_id = wpbc_clean_digit_or_csd( $booking_id ); // Check paramter if it number or comma separated list of numbers.
1394
1395 if ( is_numeric( $booking_id ) ) { // FixIn: 8.1.2.8.
1396 if ( ! wpbc_is_booking_approved( $booking_id ) ) {
1397 do_action( 'wpbc_booking_approved', $booking_id, 1 ); // FixIn: 8.7.6.1.
1398
1399 wpbc_send_email_approved( $booking_id, 1, $email_reason );
1400 }
1401 } else {
1402 $booking_id_arr = explode( ',', $booking_id );
1403 foreach ( $booking_id_arr as $bk_id ) {
1404 if ( ! wpbc_is_booking_approved( $bk_id ) ) {
1405 do_action( 'wpbc_booking_approved', $bk_id, 1 ); // FixIn: 8.7.6.1.
1406 wpbc_send_email_approved( $bk_id, 1, $email_reason );
1407 }
1408 }
1409 }
1410
1411 $db_result = wpbc_db__booking_approve( $booking_id );
1412
1413 if ( false === $db_result ) {
1414
1415 wpbc_redirect( site_url() );
1416 }
1417 }
1418
1419
1420 /**
1421 * Set as Pending specific booking and send email about this.
1422 *
1423 * @param int $booking_id - ID of booking
1424 * @param string $denyreason
1425 */
1426 function wpbc_auto_pending_booking( $booking_id, $denyreason = '' ) {
1427 // FixIn: 8.4.7.25.
1428
1429 global $wpdb;
1430
1431 $booking_id = wpbc_clean_digit_or_csd( $booking_id ); // Check paramter if it number or comma separated list of numbers.
1432
1433 if ( is_numeric( $booking_id ) ) { // FixIn: 8.1.2.8.
1434 if ( wpbc_is_booking_approved( $booking_id ) ) {
1435 wpbc_send_email_deny( $booking_id, 1, $denyreason );
1436 }
1437 } else {
1438 $booking_id_arr = explode( ',', $booking_id );
1439 foreach ( $booking_id_arr as $bk_id ) {
1440 if ( wpbc_is_booking_approved( $bk_id ) ) {
1441 wpbc_send_email_deny( $bk_id, 1, $denyreason );
1442 }
1443 }
1444 }
1445
1446 $update_sql = "UPDATE {$wpdb->prefix}bookingdates SET approved = '0' WHERE booking_id IN ({$booking_id});";
1447 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.NotPrepared, PluginCheck.Security.DirectDB.UnescapedDBParameter
1448 if ( false === $wpdb->query( $update_sql ) ) {
1449
1450 wpbc_redirect( site_url() );
1451 }
1452 }
1453
1454
1455 /**
1456 * Cancel (move to Trash) specific booking.
1457 *
1458 * @param int $booking_id - ID of booking
1459 * @param string $email_reason - reason of cancellation
1460 */
1461 function wpbc_auto_cancel_booking( $booking_id, $email_reason = '' ) {
1462 // FixIn: 8.4.7.25.
1463
1464 global $wpdb;
1465
1466 $booking_id = wpbc_clean_digit_or_csd( $booking_id ); // Check paramter if it number or comma separated list of numbers.
1467
1468 if ( empty( $email_reason ) ) { // FixIn: 8.4.7.25.
1469 // Get the reason of cancellation.
1470 $email_reason = __( 'Payment rejected', 'booking' );
1471 $auto_cancel_pending_unpaid_bk_is_send_email = get_bk_option( 'booking_auto_cancel_pending_unpaid_bk_is_send_email' );
1472 if ( 'On' === $auto_cancel_pending_unpaid_bk_is_send_email ) {
1473 $email_reason = get_bk_option( 'booking_auto_cancel_pending_unpaid_bk_email_reason' );
1474 }
1475 }
1476 // Send decline emails.
1477 wpbc_send_email_trash( $booking_id, 1, $email_reason );
1478 // FixIn: 10.12.1.5.
1479 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.PreparedSQL.InterpolatedNotPrepared, PluginCheck.Security.DirectDB.UnescapedDBParameter
1480 if ( false === $wpdb->query( "UPDATE {$wpdb->prefix}booking SET trash = 1 WHERE booking_id IN ({$booking_id})" ) ) {
1481
1482 wpbc_redirect( site_url() );
1483 }
1484 }
1485
1486
1487 // FixIn: 9.9.0.43.
1488
1489 /**
1490 * Auto approve booking and send email, after successful payment process
1491 *
1492 * 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,
1493 * 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
1494 *
1495 * @param $booking_id
1496 *
1497 * @return void
1498 */
1499 function wpbc_auto_approve_booking__after_payment( $booking_id ) {
1500 //-------------------------------------------------------------------------------------------------- // FixIn: 9.9.0.43.
1501 $is_force_again = false;
1502 if ( class_exists( 'wpdev_bk_multiuser' ) ) {
1503
1504 list( $booking_hash, $booking_resource_id ) = wpbc_hash__get_booking_hash__resource_id( $booking_id );
1505
1506 $user_id = apply_bk_filter( 'get_user_of_this_bk_resource', false, $booking_resource_id );
1507
1508 $is_booking_resource_user_super_admin = apply_bk_filter( 'is_user_super_admin', $user_id );
1509
1510 if (
1511 ( 'On' == get_bk_option( 'booking_super_admin_receive_regular_user_payments' ) )
1512 && ( ! $is_booking_resource_user_super_admin )
1513 ) {
1514 // Finish "Super-User" forcing
1515 make_bk_action( 'finish_force_using_this_user' );
1516 //Reactivate data for "regular user
1517 make_bk_action( 'check_multiuser_params_for_client_side_by_user_id', $user_id );
1518
1519 $is_force_again = true;
1520 }
1521 }
1522 // -------------------------------------------------------------------------------------------------
1523
1524 wpbc_auto_approve_booking( $booking_id );
1525
1526 if ( $is_force_again ) { // FixIn: 9.9.0.43.
1527 make_bk_action( 'make_force_using_this_user', - 999 ); // '-999' - This ID "by default" is the ID of super booking admin user
1528 }
1529 }
1530
1531
1532 /**
1533 * Auto cancel booking and send email, after successful payment process
1534 *
1535 * 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,
1536 * 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
1537 *
1538 * @param $booking_id
1539 *
1540 * @return void
1541 */
1542 function wpbc_auto_cancel_booking__after_payment( $booking_id ) {
1543 //-------------------------------------------------------------------------------------------------- // FixIn: 9.9.0.43.
1544 $is_force_again = false;
1545 if ( class_exists( 'wpdev_bk_multiuser' ) ) {
1546
1547 list( $booking_hash, $booking_resource_id ) = wpbc_hash__get_booking_hash__resource_id( $booking_id );
1548
1549 $user_id = apply_bk_filter( 'get_user_of_this_bk_resource', false, $booking_resource_id );
1550
1551 $is_booking_resource_user_super_admin = apply_bk_filter( 'is_user_super_admin', $user_id );
1552
1553 if (
1554 ( 'On' == get_bk_option( 'booking_super_admin_receive_regular_user_payments' ) )
1555 && ( ! $is_booking_resource_user_super_admin )
1556 ) {
1557 // Finish "Super-User" forcing
1558 make_bk_action( 'finish_force_using_this_user' );
1559 //Reactivate data for "regular user
1560 make_bk_action( 'check_multiuser_params_for_client_side_by_user_id', $user_id );
1561
1562 $is_force_again = true;
1563 }
1564 }
1565 // -------------------------------------------------------------------------------------------------
1566
1567 wpbc_auto_cancel_booking( $booking_id );
1568
1569 if ( $is_force_again ) { // FixIn: 9.9.0.43.
1570 make_bk_action( 'make_force_using_this_user', - 999 ); // '-999' - This ID "by default" is the ID of super booking admin user
1571 }
1572 }
1573 // </editor-fold>
1574
1575
1576 // <editor-fold defaultstate="collapsed" desc=" == Logs for Notes / remarks == " >
1577
1578 /**
1579 * Add Log info to Notes of bookings
1580 *
1581 * @param array | int $booking_id_arr
1582 * @param string $message
1583 */
1584 function wpbc_db__add_log_info( $booking_id_arr, $message ) {
1585
1586 if ( get_bk_option( 'booking_log_booking_actions' ) !== 'On' ) {
1587 return;
1588 }
1589
1590 $booking_id_arr = (array) $booking_id_arr;
1591
1592 $is_append = true;
1593 foreach ( $booking_id_arr as $booking_id ) {
1594 $date_time = date_i18n( '[Y-m-d H:i] ' );
1595 make_bk_action('wpdev_make_update_of_remark' , $booking_id , $date_time . $message , $is_append ); // FixIn: 9.1.2.14.
1596 }
1597 }
1598
1599 // </editor-fold>
1600
1601
1602 // <editor-fold defaultstate="collapsed" desc=" == CSV export support function == " >
1603
1604 /**
1605 * Get Path from request URL. E.g. 'my-category/file.csv' from url, like https://server.com/my-category/file.csv
1606 *
1607 * It can detect internal sub folder or WordPress, like http://server.com/my-website/
1608 *
1609 * @return false|string
1610 */
1611 function wpbc_get_request_url_path(){
1612
1613 $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 */
1614 $my_parsed_url = wp_parse_url( $server_request_uri );
1615
1616 if ( false === $my_parsed_url ) { // seriously malformed URLs, wp_parse_url() may return FALSE.
1617 return false;
1618 }
1619
1620 $my_parsed_url_path = trim( $my_parsed_url['path'] );
1621 $my_parsed_url_path = trim( $my_parsed_url_path, '/' );
1622
1623
1624 // Check internal sub folder of WP, like http://server.com/my-website/[ ... LINK ...] // FixIn: 2.0.5.4.
1625 if ( function_exists( 'wp_parse_url' ) ) {
1626 $wp_home_server_url = wp_parse_url( home_url() );
1627 } else {
1628 $wp_home_server_url = @wp_parse_url( home_url() );
1629 }
1630
1631 if ( ( false !== $wp_home_server_url ) && ( ! empty( $wp_home_server_url['path'] ) ) ) { // seriously malformed URLs, wp_parse_url() may return FALSE.
1632
1633 $server_url_sufix = trim( $wp_home_server_url[ 'path' ] ); // [path] => /my-website
1634 $server_url_sufix = trim( $server_url_sufix, '/' ); // my-website
1635
1636 if ( ! empty( $server_url_sufix ) ) {
1637
1638 $check_sufix = substr( $my_parsed_url_path, 0, strlen( $server_url_sufix ) );
1639
1640 if ( $check_sufix === $server_url_sufix ) {
1641
1642 $my_parsed_url_path = substr( $my_parsed_url_path, strlen( $server_url_sufix ) );
1643
1644 $my_parsed_url_path = trim( $my_parsed_url_path, '/' );
1645 }
1646 }
1647 } //End FixIn: 2.0.5.4
1648
1649 return $my_parsed_url_path;
1650 }
1651
1652 // </editor-fold>
1653
1654
1655 // <editor-fold defaultstate="collapsed" desc=" == SKIP BLANK EMAIL == " >
1656
1657
1658 /**
1659 * Check if this email is NOT blank email to SKIP email sending -- from autofill fast booking creation at Booking > Add booking page.
1660 *
1661 * Currently, plugin use 'blank@wpbookingmanager.com' for all blank bookings, previously it was used 'admin@blank.com'
1662 *
1663 * @param $email_address
1664 * @param $email_content
1665 *
1666 * @return bool
1667 */
1668 function wpbc_is_not_blank_email( $email_address, $email_content ) {
1669
1670 // Previously: if ( ( strpos( $to, '@blank.com' ) === false ) && ( strpos( $replace['content'], 'admin@blank.com' ) === false ) ) { ->send(...) }
1671
1672 if (
1673 ( false === strpos( $email_address, '@blank.com' ) )
1674 && ( false === strpos( $email_content, 'admin@blank.com' ) )
1675 && ( false === strpos( $email_address, '@wpbookingmanager.com' ) )
1676 && ( false === strpos( $email_content, 'blank@wpbookingmanager.com' ) )
1677 ) {
1678 return true;
1679 }
1680
1681 return false;
1682 }
1683
1684 // </editor-fold>
1685
1686
1687 // <editor-fold defaultstate="collapsed" desc=" == PHP PERFORMANCE == " >
1688
1689
1690 /**
1691 * Start calculation of time for execution of specific part of CODE
1692 *
1693 * @param string $name name of section
1694 * @param array $php_performance
1695 *
1696 * @return array
1697 *
1698 * Example:
1699 *
1700 * $php_performance = wpbc_php_performance_START( 'emails_sending' , $php_performance );
1701 *
1702 * ... some code here ...
1703 *
1704 * $php_performance = wpbc_php_performance_END( 'emails_sending' , $php_performance );
1705 *
1706 * echo 'Time of execution: ' . $php_performancep['emails_sending']
1707 *
1708 */
1709 function wpbc_php_performance_START( $name, $php_performance ) {
1710
1711 if ( empty( $php_performance ) ) {
1712 $php_performance = array();
1713 }
1714
1715 $php_performance[ $name ] = microtime( true );
1716
1717 return $php_performance;
1718 }
1719
1720 /**
1721 * End calculation of time for execution of specific part of CODE
1722 *
1723 * @param string $name name of section
1724 * @param array $php_performance
1725 *
1726 * @return array
1727 *
1728 * Example:
1729 *
1730 * $php_performance = wpbc_php_performance_START( 'emails_sending' , $php_performance );
1731 *
1732 * ... some code here ...
1733 *
1734 * $php_performance = wpbc_php_performance_END( 'emails_sending' , $php_performance );
1735 *
1736 * echo 'Time of execution: ' . $php_performancep['emails_sending']
1737 *
1738 */
1739 function wpbc_php_performance_END( $name, $php_performance ) {
1740
1741 if ( empty( $php_performance ) ) {
1742 $php_performance = array();
1743 }
1744 if ( empty( $php_performance[ $name ] ) ) {
1745 $php_performance[ $name ] = microtime( true );
1746 }
1747
1748 $php_performance[ $name ] = microtime( true ) - $php_performance[ $name ];
1749
1750 return $php_performance;
1751 }
1752
1753 /**
1754 * Set maximum number of seconds for execution.
1755 *
1756 * @param $limit_in_seconds_int
1757 *
1758 * @return void
1759 */
1760 function wpbc_set_limit_php( $limit_in_seconds_int = 300 ) {
1761
1762 WPBC_Action_Scheduler_Compatibility::raise_memory_limit();
1763 WPBC_Action_Scheduler_Compatibility::raise_time_limit( $limit_in_seconds_int );
1764 }
1765
1766
1767 // </editor-fold>
1768
1769
1770
1771 /**
1772 * Temp fix of styles for edit specific season filter or rate.
1773 *
1774 * @return void
1775 */
1776 function wpbc_add_css_to_hide_seasons() {
1777
1778 // TODO: 2025-05-03 temp fix of view edit filter
1779 ?>
1780 <style tye="text/css">
1781 .wpdvlp-sub-tabs,
1782 #wpbc_dcoupons_table, #wpbc_discountcoupons,
1783 #bulk-action-selector-bottom,
1784 #toolbar_booking_resources,
1785 #toolbar_seasonfilters,
1786 #wpbc_seasonfilters,
1787 #wpbc_booking_resource_table{
1788 display: none !important;
1789 }
1790 .wpbc_round_white_panel {
1791 background: #fff;
1792 padding: 1px 20px 20px;
1793 border-radius: 10px
1794 }
1795 .header_for_cost_object_edit {
1796 font-size: 20px;
1797 padding: 0 0 15px;
1798 border-bottom: 2px solid #f2f2f2;
1799 margin: 15px 0;
1800 line-height: 1.5;
1801 display: flex;
1802 flex-flow: row nowrap;
1803 justify-content: space-between;
1804 align-items: flex-start;
1805 }
1806 .in_header_container_for_resource_title {
1807 color: #5379aa;
1808 margin-left: 0.3em;
1809 }
1810 .header_for_cost_object_edit__close i.wpbc_icn_close::before {
1811 font-size: 22px;
1812 }
1813 </style>
1814 <?php
1815 }
1816