| @@ -8,8 +8,9 @@ | ||
| 8 | 8 | use FluentBooking\App\Models\CalendarSlot; |
| 9 | 9 | use FluentBooking\App\Services\BookingFieldService; |
| 10 | 10 | use FluentBooking\App\Services\BookingService; |
| 11 | 11 | use FluentBooking\App\Services\DateTimeHelper; |
| 12 | +use FluentBooking\App\Services\PublicTransStrings; | |
| 12 | 13 | use FluentBooking\App\Services\Helper; |
| 13 | 14 | use FluentBooking\App\Services\LandingPage\LandingPageHandler; |
| 14 | 15 | use FluentBooking\App\Services\LandingPage\LandingPageHelper; |
| 15 | 16 | use FluentBooking\App\Hooks\Handlers\TimeSlotServiceHandler; |
| @@ -554,92 +555,12 @@ | ||
| 554 | 555 | 'ajaxurl' => admin_url('admin-ajax.php'), |
| 555 | 556 | 'timezones' => DateTimeHelper::getFlatGroupedTimeZones(), |
| 556 | 557 | 'current_person' => $currentPerson, |
| 557 | 558 | 'start_day' => $startDay, |
| 558 | - 'i18' => [ | |
| 559 | - 'Timezone' => __('Timezone', 'fluent-booking'), | |
| 560 | - 'Day' => __('Day', 'fluent-booking'), | |
| 561 | - 'Days' => __('Days', 'fluent-booking'), | |
| 562 | - 'Hour' => __('Hour', 'fluent-booking'), | |
| 563 | - 'Hours' => __('Hours', 'fluent-booking'), | |
| 564 | - 'Minute' => __('Minute', 'fluent-booking'), | |
| 565 | - 'Minutes' => __('Minutes', 'fluent-booking'), | |
| 566 | - 'week' => __('week', 'fluent-booking'), | |
| 567 | - 'month' => __('month', 'fluent-booking'), | |
| 568 | - 'year' => __('year', 'fluent-booking'), | |
| 569 | - 'weeks' => __('weeks', 'fluent-booking'), | |
| 570 | - 'months' => __('months', 'fluent-booking'), | |
| 571 | - 'years' => __('years', 'fluent-booking'), | |
| 572 | - 'Every' => __('Every', 'fluent-booking'), | |
| 573 | - 'for' => __('for', 'fluent-booking'), | |
| 574 | - 'Number of Occurrences' => __('Number of Occurrences', 'fluent-booking'), | |
| 575 | - 'occurrence' => __('occurrence', 'fluent-booking'), | |
| 576 | - 'occurrences' => __('occurrences', 'fluent-booking'), | |
| 577 | - 'You can only book up to' => __('You can only book up to', 'fluent-booking'), | |
| 578 | - 'at a time' => __('at a time', 'fluent-booking'), | |
| 579 | - 'Enter Details' => __('Enter Details', 'fluent-booking'), | |
| 580 | - 'Summary' => __('Summary', 'fluent-booking'), | |
| 581 | - 'Payment Details' => __('Payment Details', 'fluent-booking'), | |
| 582 | - 'Item' => __('Item', 'fluent-booking'), | |
| 583 | - 'Price' => __('Price', 'fluent-booking'), | |
| 584 | - 'Quantity' => __('Quantity', 'fluent-booking'), | |
| 585 | - 'Subtotal:' => __('Subtotal:', 'fluent-booking'), | |
| 586 | - 'Total:' => __('Total:', 'fluent-booking'), | |
| 587 | - 'Total Payment' => __('Total Payment', 'fluent-booking'), | |
| 588 | - 'Payment Method' => __('Payment Method', 'fluent-booking'), | |
| 589 | - 'Pay Now' => __('Pay Now', 'fluent-booking'), | |
| 590 | - 'processing' => __('Processing', 'fluent-booking'), | |
| 591 | - 'date_time_config' => DateTimeHelper::getI18nDateTimeConfig(), | |
| 592 | - 'Country' => __('Country', 'fluent-booking'), | |
| 593 | - '12h' => _x('12h', 'date time format switch', 'fluent-booking'), | |
| 594 | - '24h' => _x('24h', 'date time format switch', 'fluent-booking'), | |
| 595 | - 'spots left' => _x('spots left', 'for how many spots left for available booking', 'fluent-booking'), | |
| 596 | - 'spots remaining' => _x('spots remaining', 'for how many spots remaining for available booking', 'fluent-booking'), | |
| 597 | - 'Next' => _x('Next', 'Booking form spot selection', 'fluent-booking'), | |
| 598 | - 'Select on the Next Step' => __('Select on the Next Step', 'fluent-booking'), | |
| 599 | - 'location options' => __('location options', 'fluent-booking'), | |
| 600 | - 'Your address' => __('Your address', 'fluent-booking'), | |
| 601 | - 'Organizer Phone Number' => __('Organizer Phone Number', 'fluent-booking'), | |
| 602 | - 'In Person (Attendee Address)' => __('In Person (Attendee Address)', 'fluent-booking'), | |
| 603 | - 'In Person (Organizer Address)' => __('In Person (Organizer Address)', 'fluent-booking'), | |
| 604 | - 'Attendee Phone Number' => __('Attendee Phone Number', 'fluent-booking'), | |
| 605 | - 'Google Meet' => __('Google Meet', 'fluent-booking'), | |
| 606 | - 'Zoom Meeting' => __('Zoom Meeting', 'fluent-booking'), | |
| 607 | - 'Online Meeting' => __('Online Meeting', 'fluent-booking'), | |
| 608 | - 'Phone Call' => __('Phone Call', 'fluent-booking'), | |
| 609 | - 'Processing...' => __('Processing...', 'fluent-booking'), | |
| 610 | - 'Loading Payment Processor...' => __('Loading Payment Processor...', 'fluent-booking'), | |
| 611 | - 'PM' => __('PM', 'fluent-booking'), | |
| 612 | - 'AM' => __('AM', 'fluent-booking'), | |
| 613 | - 'Name' => __('Name', 'fluent-booking'), | |
| 614 | - 'Email' => __('Email', 'fluent-booking'), | |
| 615 | - 'Date' => __('Date', 'fluent-booking'), | |
| 616 | - 'Time' => __('Time', 'fluent-booking'), | |
| 617 | - 'per occurrence' => __('per occurrence', 'fluent-booking'), | |
| 618 | - 'per guest' => __('per guest', 'fluent-booking'), | |
| 619 | - 'Add guest' => __('Add guest', 'fluent-booking'), | |
| 620 | - 'Add guests' => __('Add guests', 'fluent-booking'), | |
| 621 | - 'Add another' => __('Add another', 'fluent-booking'), | |
| 622 | - 'Choose File' => __('Choose File', 'fluent-booking'), | |
| 623 | - 'This field is required.' => __('This field is required.', 'fluent-booking'), | |
| 624 | - 'No availability in' => __('No availability in', 'fluent-booking'), | |
| 625 | - 'View next month' => __('View next month', 'fluent-booking'), | |
| 626 | - 'View previous month' => __('View previous month', 'fluent-booking'), | |
| 627 | - 'Back to Date Selection' => __('Back to Date Selection', 'fluent-booking'), | |
| 628 | - 'Go to previous page' => __('Go to previous page', 'fluent-booking'), | |
| 629 | - 'Remove this time slot' => __('Remove this time slot', 'fluent-booking'), | |
| 630 | - 'Remove coupon' => __('Remove coupon', 'fluent-booking'), | |
| 631 | - 'Select this time' => __('Select this time', 'fluent-booking'), | |
| 632 | - 'Confirm Time' => __('Confirm Time', 'fluent-booking'), | |
| 633 | - '12 hour time format' => __('12 hour time format', 'fluent-booking'), | |
| 634 | - '24 hour time format' => __('24 hour time format', 'fluent-booking'), | |
| 635 | - 'No_payment_method_description' => __('No activated payment method found. If you are an admin please check the event payment settings', 'fluent-booking'), | |
| 636 | - 'Please fill up the required data' => __('Please fill up the required data', 'fluent-booking'), | |
| 637 | - 'Please select a valid payment method' => __('Please select a valid payment method', 'fluent-booking'), | |
| 638 | - 'Please Select' => __('Please Select', 'fluent-booking'), | |
| 639 | - 'Something is wrong!' => __('Something is wrong!', 'fluent-booking'), | |
| 640 | - 'Requires Confirmation' => __('Requires Confirmation', 'fluent-booking'), | |
| 641 | - ], | |
| 559 | + // Generated from the i18() calls in resources/public; see scripts/i18n.js. | |
| 560 | + 'i18' => array_merge(PublicTransStrings::getStrings(), [ | |
| 561 | + 'date_time_config' => DateTimeHelper::getI18nDateTimeConfig(), | |
| 562 | + ]), | |
| 642 | 563 | 'theme' => Arr::get(get_option('_fluent_booking_settings'), 'theme', 'system-default'), |
| 643 | 564 | 'currency_settings' => CurrenciesHelper::getGlobalCurrencySettings() |
| 644 | 565 | ]; |
| 645 | 566 | |
| @@ -852,10 +773,12 @@ | ||
| 852 | 773 | if (is_wp_error($timeSlotService)) { |
| 853 | 774 | return TimeSlotServiceHandler::sendError($timeSlotService, $calendarEvent, $timezone); |
| 854 | 775 | } |
| 855 | 776 | |
| 856 | - $availableSpot = $timeSlotService->isSpotAvailable($bookingData['start_time'], $bookingData['end_time'], $duration); | |
| 777 | + $isSlotLocked = Helper::lockRoundRobinSlot($calendarEvent, $bookingData['start_time'], $bookingData['end_time']); | |
| 857 | 778 | |
| 779 | + $availableSpot = $isSlotLocked ? $timeSlotService->isSpotAvailable($bookingData['start_time'], $bookingData['end_time'], $duration) : false; | |
| 780 | + | |
| 858 | 781 | if (!$availableSpot) { |
| 859 | 782 | wp_send_json([ |
| 860 | 783 | 'message' => __('This selected time slot is not available. Maybe someone booked the spot just a few seconds ago.', 'fluent-booking') |
| 861 | 784 | ], 422); |
| @@ -1014,9 +937,9 @@ | ||
| 1014 | 937 | 'min_bookable_date' => $calendarEvent->getMinBookableDateTime(), |
| 1015 | 938 | 'is_display_spots' => $calendarEvent->isDisplaySpots(), |
| 1016 | 939 | 'duration' => $calendarEvent->getDefaultDuration(), |
| 1017 | 940 | 'title' => $calendarEvent->title, |
| 1018 | - 'location_settings' => $this->sanitizePublicLocationSettings($calendarEvent->location_settings), | |
| 941 | + 'location_settings' => LocationService::sanitizePublicLocationSettings($calendarEvent->location_settings), | |
| 1019 | 942 | 'location_icon_html' => $calendarEvent->location_icon_html, |
| 1020 | 943 | 'description' => $calendarEvent->description, |
| 1021 | 944 | 'pre_selects' => null, |
| 1022 | 945 | 'settings' => $this->sanitizePublicEventSettings($calendarEvent->settings), |
| @@ -1050,47 +973,8 @@ | ||
| 1050 | 973 | $eventVars['team_member_profiles'] = $calendarEvent->getAuthorProfiles(true); |
| 1051 | 974 | } |
| 1052 | 975 | |
| 1053 | 976 | return apply_filters('fluent_booking/public_event_vars', $eventVars, $calendarEvent); |
| 1054 | - } | |
| 1055 | - | |
| 1056 | - private function sanitizePublicLocationSettings($locationSettings) | |
| 1057 | - { | |
| 1058 | - if (!is_array($locationSettings)) { | |
| 1059 | - return []; | |
| 1060 | - } | |
| 1061 | - | |
| 1062 | - $safe = []; | |
| 1063 | - foreach ($locationSettings as $location) { | |
| 1064 | - if (!is_array($location)) { | |
| 1065 | - continue; | |
| 1066 | - } | |
| 1067 | - | |
| 1068 | - $type = Arr::get($location, 'type'); | |
| 1069 | - $displayOnBooking = Arr::get($location, 'display_on_booking') === 'yes'; | |
| 1070 | - | |
| 1071 | - $sanitized = [ | |
| 1072 | - 'type' => $type, | |
| 1073 | - 'title' => Arr::get($location, 'title'), | |
| 1074 | - 'display_on_booking' => Arr::get($location, 'display_on_booking', 'no'), | |
| 1075 | - ]; | |
| 1076 | - | |
| 1077 | - // Only expose host-private fields when the host explicitly opted | |
| 1078 | - // in to display them before booking. | |
| 1079 | - if ($displayOnBooking) { | |
| 1080 | - if ($type === 'online_meeting') { | |
| 1081 | - $sanitized['meeting_link'] = Arr::get($location, 'meeting_link'); | |
| 1082 | - } elseif ($type === 'phone_organizer') { | |
| 1083 | - $sanitized['host_phone_number'] = Arr::get($location, 'host_phone_number'); | |
| 1084 | - } elseif (in_array($type, ['in_person_organizer', 'custom'], true)) { | |
| 1085 | - $sanitized['description'] = Arr::get($location, 'description'); | |
| 1086 | - } | |
| 1087 | - } | |
| 1088 | - | |
| 1089 | - $safe[] = $sanitized; | |
| 1090 | - } | |
| 1091 | - | |
| 1092 | - return $safe; | |
| 1093 | 977 | } |
| 1094 | 978 | |
| 1095 | 979 | private function sanitizePublicEventSettings($settings) |
| 1096 | 980 | { |