| @@ -1,4 +1,4 @@ | ||
| 1 | 1 | <?php |
| 2 | 2 | /** |
| 3 | 3 | * @version 1.0 |
| 4 | 4 | * @package Booking Calendar |
| @@ -8,8 +8,10 @@ | ||
| 8 | 8 | * @author wpdevelop |
| 9 | 9 | * @link https://wpbookingcalendar.com/ |
| 10 | 10 | * @email info@wpbookingcalendar.com |
| 11 | 11 | * |
| 12 | + * @file ../includes/_functions/str_regex.php | |
| 13 | + * | |
| 12 | 14 | * @modified 2024-05-14 |
| 13 | 15 | */ |
| 14 | 16 | |
| 15 | 17 | if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly |
| @@ -288,18 +290,21 @@ | ||
| 288 | 290 | * @return mixed false | array( $fields_count, $fields_matches ) |
| 289 | 291 | */ |
| 290 | 292 | function wpbc_get_fields_from_booking_form( $booking_form = '' ){ |
| 291 | 293 | |
| 292 | - if ( empty( $booking_form ) ) { | |
| 293 | - $booking_form = get_bk_option( 'booking_form' ); | |
| 294 | - } | |
| 294 | + if ( empty( $booking_form ) ) { | |
| 295 | + $booking_form = function_exists( 'wpbc_get__booking_form_fields__configuration' ) ? wpbc_get__booking_form_fields__configuration( wpbc_get_default_resource(), 'standard' ) : ''; | |
| 296 | + } | |
| 295 | 297 | |
| 296 | 298 | $types = 'text[*]?|email[*]?|time[*]?|textarea[*]?|select[*]?|selectbox[*]?|checkbox[*]?|radio|acceptance|captchac|captchar|file[*]?|quiz'; |
| 297 | - $regex = '%\[\s*(' . $types . ')(\s+[a-zA-Z][0-9a-zA-Z:._-]*)([-0-9a-zA-Z:#_/|\s]*)?((?:\s*(?:"[^"]*"|\'[^\']*\'))*)?\s*\]%'; | |
| 298 | - $regex2 = '%\[\s*(country[*]?|starttime[*]?|endtime[*]?)(\s*[a-zA-Z]*[0-9a-zA-Z:._-]*)([-0-9a-zA-Z:#_/|\s]*)*((?:\s*(?:"[^"]*"|\'[^\']*\'))*)?\s*\]%'; | |
| 299 | - $fields_count = preg_match_all( $regex, $booking_form, $fields_matches ); | |
| 300 | - $fields_count2 = preg_match_all( $regex2, $booking_form, $fields_matches2 ); | |
| 299 | + $fields_data = wpbc_get_booking_form_shortcode_fields_by_types( $booking_form, $types ); | |
| 300 | + $fields_count = $fields_data[0]; | |
| 301 | + $fields_matches = $fields_data[1]; | |
| 301 | 302 | |
| 303 | + $fields_data2 = wpbc_get_booking_form_shortcode_fields_by_types( $booking_form, 'country[*]?|starttime[*]?|endtime[*]?', false, true ); | |
| 304 | + $fields_count2 = $fields_data2[0]; | |
| 305 | + $fields_matches2 = $fields_data2[1]; | |
| 306 | + | |
| 302 | 307 | //Gathering Together 2 arrays $fields_matches and $fields_matches2 |
| 303 | 308 | foreach ( $fields_matches2 as $key => $value ) { |
| 304 | 309 | if ( $key == 2 ) { |
| 305 | 310 | $value = $fields_matches2[1]; |
| @@ -325,16 +330,16 @@ | ||
| 325 | 330 | * @return mixed false | array( $fields_count, $fields_matches ) |
| 326 | 331 | */ |
| 327 | 332 | function wpbc_get_select_checkbox_fields_from_booking_form( $booking_form = '' ){ |
| 328 | 333 | |
| 329 | - if ( empty( $booking_form ) ) | |
| 330 | - $booking_form = get_bk_option( 'booking_form' ); | |
| 334 | + if ( empty( $booking_form ) ) | |
| 335 | + $booking_form = function_exists( 'wpbc_get__booking_form_fields__configuration' ) ? wpbc_get__booking_form_fields__configuration( wpbc_get_default_resource(), 'standard' ) : ''; | |
| 331 | 336 | |
| 332 | 337 | $types = 'select[*]?|selectbox[*]?|checkbox[*]?|radio[*]?'; // FixIn: 8.1.3.7. |
| 333 | - $regex = '%\[\s*(' . $types . ')(\s+[a-zA-Z][0-9a-zA-Z:._-]*)([-0-9a-zA-Z:#_/|\s]*)?((?:\s*(?:"[^"]*"|\'[^\']*\'))*)?\s*\]%'; | |
| 338 | + $fields_data = wpbc_get_booking_form_shortcode_fields_by_types( $booking_form, $types ); | |
| 339 | + $fields_count = $fields_data[0]; | |
| 340 | + $fields_matches = $fields_data[1]; | |
| 334 | 341 | |
| 335 | - $fields_count = preg_match_all($regex, $booking_form, $fields_matches) ; | |
| 336 | - | |
| 337 | 342 | if ( $fields_count > 0 ) |
| 338 | 343 | return array( $fields_count, $fields_matches ); |
| 339 | 344 | else return false; |
| 340 | 345 | } |
| @@ -339,8 +344,110 @@ | ||
| 339 | 344 | else return false; |
| 340 | 345 | } |
| 341 | 346 | |
| 342 | 347 | |
| 348 | +/** | |
| 349 | + * Get shortcode fields in the legacy preg_match_all() result shape used by settings pages. | |
| 350 | + * | |
| 351 | + * The parser keeps option assignments such as default="1" in the options group and exposes only standalone | |
| 352 | + * quoted tokens as field values. | |
| 353 | + * | |
| 354 | + * @param string $booking_form | |
| 355 | + * @param string $types | |
| 356 | + * @param bool $is_name_required | |
| 357 | + * @param bool $is_name_forced_to_type | |
| 358 | + * | |
| 359 | + * @return array | |
| 360 | + */ | |
| 361 | +function wpbc_get_booking_form_shortcode_fields_by_types( $booking_form, $types, $is_name_required = true, $is_name_forced_to_type = false ) { | |
| 362 | + | |
| 363 | + $fields_matches = array_fill( 0, 5, array() ); | |
| 364 | + $regex = '%\[\s*(' . $types . ')(?=\s|\])((?:[^\]"\']+|"[^"]*"|\'[^\']*\')*)\]%'; | |
| 365 | + $found_fields = array(); | |
| 366 | + | |
| 367 | + preg_match_all( $regex, $booking_form, $found_fields, PREG_SET_ORDER ); | |
| 368 | + | |
| 369 | + foreach ( $found_fields as $found_field ) { | |
| 370 | + | |
| 371 | + $shortcode_tail = $found_field[2]; | |
| 372 | + $field_name = ''; | |
| 373 | + $field_tail = $shortcode_tail; | |
| 374 | + | |
| 375 | + if ( $is_name_forced_to_type ) { | |
| 376 | + $field_name = $found_field[1]; | |
| 377 | + } elseif ( preg_match( '%^\s*([a-zA-Z][0-9a-zA-Z:._-]*)(.*)$%s', $shortcode_tail, $shortcode_parts ) ) { | |
| 378 | + $field_name = $shortcode_parts[1]; | |
| 379 | + $field_tail = $shortcode_parts[2]; | |
| 380 | + } | |
| 381 | + | |
| 382 | + if ( $is_name_required && ( '' === $field_name ) ) { | |
| 383 | + continue; | |
| 384 | + } | |
| 385 | + | |
| 386 | + if ( '' === $field_name ) { | |
| 387 | + $field_name = $found_field[1]; | |
| 388 | + } | |
| 389 | + | |
| 390 | + list( $shortcode_options, $shortcode_values ) = wpbc_parse_form_shortcode_options_values( $field_tail ); | |
| 391 | + | |
| 392 | + $fields_matches[0][] = trim( $found_field[0] ); | |
| 393 | + $fields_matches[1][] = trim( $found_field[1] ); | |
| 394 | + $fields_matches[2][] = trim( $field_name ); | |
| 395 | + $fields_matches[3][] = trim( $shortcode_options ); | |
| 396 | + $fields_matches[4][] = trim( $shortcode_values ); | |
| 397 | + } | |
| 398 | + | |
| 399 | + return array( count( $fields_matches[0] ), $fields_matches ); | |
| 400 | +} | |
| 401 | + | |
| 402 | + | |
| 403 | +if ( ! function_exists( 'wpbc_parse_form_shortcode_options_values' ) ) { | |
| 404 | + function wpbc_parse_form_shortcode_options_values( $shortcode_tail ){ | |
| 405 | + | |
| 406 | + $shortcode_options = trim( $shortcode_tail ); | |
| 407 | + $shortcode_values = ''; | |
| 408 | + | |
| 409 | + $value_matches = array(); | |
| 410 | + preg_match_all( '%(?:"[^"]*"|\'[^\']*\')%', $shortcode_tail, $value_matches, PREG_OFFSET_CAPTURE ); | |
| 411 | + | |
| 412 | + $standalone_values = array(); | |
| 413 | + foreach ( $value_matches[0] as $value_match ) { | |
| 414 | + $value_offset = $value_match[1]; | |
| 415 | + $prev_offset = $value_offset - 1; | |
| 416 | + | |
| 417 | + if ( ( $prev_offset >= 0 ) && ! ctype_space( $shortcode_tail[ $prev_offset ] ) ) { | |
| 418 | + continue; | |
| 419 | + } | |
| 420 | + | |
| 421 | + while ( ( $prev_offset >= 0 ) && ctype_space( $shortcode_tail[ $prev_offset ] ) ) { | |
| 422 | + $prev_offset--; | |
| 423 | + } | |
| 424 | + | |
| 425 | + if ( ( $prev_offset >= 0 ) && in_array( $shortcode_tail[ $prev_offset ], array( '=', ':' ), true ) ) { | |
| 426 | + continue; | |
| 427 | + } | |
| 428 | + | |
| 429 | + $standalone_values[] = $value_match; | |
| 430 | + } | |
| 431 | + | |
| 432 | + if ( ! empty( $standalone_values ) ) { | |
| 433 | + $shortcode_options = trim( substr( $shortcode_tail, 0, $standalone_values[0][1] ) ); | |
| 434 | + $shortcode_values = implode( | |
| 435 | + ' ', | |
| 436 | + array_map( | |
| 437 | + function ( $value_match ) { | |
| 438 | + return $value_match[0]; | |
| 439 | + }, | |
| 440 | + $standalone_values | |
| 441 | + ) | |
| 442 | + ); | |
| 443 | + } | |
| 444 | + | |
| 445 | + return array( $shortcode_options, $shortcode_values ); | |
| 446 | + } | |
| 447 | +} | |
| 448 | + | |
| 449 | + | |
| 343 | 450 | // --------------------------------------------------------------------------------------------------------------------- |
| 344 | 451 | // Used in 'Search Availability' functionality |
| 345 | 452 | // --------------------------------------------------------------------------------------------------------------------- |
| 346 | 453 | |
| @@ -523,5 +630,5 @@ | ||
| 523 | 630 | $pattern = '/<\/script>/i'; |
| 524 | 631 | $result = preg_replace( $pattern, '#>', $result ); |
| 525 | 632 | |
| 526 | 633 | return $result; |
| 527 | -} | |
| 634 | +} | |