PluginProbe
Fluent Booking – The Ultimate Appointments Scheduling, Events Booking, Events Calendar Solution / 2.5.0
Fluent Booking – The Ultimate Appointments Scheduling, Events Booking, Events Calendar Solution v2.5.0
2.5.0 2.4.0 2.3.0 2.2.5 2.2.0 2.1.2 2.1.1 trunk 1.10.0 1.10.01 1.10.02 1.5.0 1.5.01 1.5.02 1.5.1 1.5.10 1.5.20 1.5.21 1.5.22 1.5.23 1.5.24 1.5.25 1.6.0 1.7.0 1.7.1 All 34 releases
← All changes | app/Services/LandingPage/LandingPageHandler.php +71 -33 1.5.21 → 2.5.0 View file →
@@ -12,8 +12,9 @@
12 12 use FluentBooking\App\Services\BookingService;
13 13 use FluentBooking\App\Services\Helper;
14 14 use FluentBooking\Framework\Support\Arr;
15 15 use FluentBooking\Framework\Support\Collection;
16 +use FluentBooking\App\Vite;
16 17
17 18 class LandingPageHandler
18 19 {
19 20 public function boot()
@@ -39,15 +40,23 @@
39 40 }
40 41
41 42 $authorSlug = sanitize_text_field($urlParts[1]);
42 43
44 + if (isset($_GET['embedded'])) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended
45 + $this->handleEmbeddedStyle();
46 + }
47 +
43 48 $this->routeView($authorSlug, Arr::get($urlParts, 2, null));
44 49 }
45 50
46 51 public function handleUrlParamsPage()
47 52 {
48 - $route = sanitize_text_field($_GET['fluent-booking']); // phpcs:ignore WordPress.Security.NonceVerification.Recommended
53 + $route = isset($_GET['fluent-booking']) ? sanitize_text_field(wp_unslash($_GET['fluent-booking'])) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Recommended
49 54
55 + if (isset($_GET['embedded'])) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended
56 + $this->handleEmbeddedStyle();
57 + }
58 +
50 59 if ($route == 'booking') {
51 60 $this->handleAfterBookingPage();
52 61 return;
53 62 }
@@ -90,9 +99,9 @@
90 99 ->first();
91 100 if (!$slot) {
92 101 return;
93 102 }
94 - $this->renderBookingView($calendar, $slot);
103 + return $this->renderBookingView($calendar, $slot);
95 104 }
96 105
97 106 $this->renderHostView($calendar);
98 107 }
@@ -103,9 +112,9 @@
103 112 $settings = LandingPageHelper::getSettings($calendar, 'public');
104 113
105 114 $activeEvents = CalendarSlot::where('calendar_id', $calendar->id)
106 115 ->where('status', 'active');
107 -
116 +
108 117 if ($settings['show_type'] != 'all') {
109 118 $activeEvents = $activeEvents->whereIn('id', $settings['enabled_slots']);
110 119 }
111 120
@@ -145,9 +154,8 @@
145 154 $activeEvent->locations = $activeEvent->defaultLocationHtml();
146 155 do_action_ref_array('fluent_booking/landing_page_event', [&$activeEvent]);
147 156 }
148 157
149 - $assetUrl = App::getInstance('url.assets');
150 158 $data = [
151 159 'calendar' => $calendar,
152 160 'events' => $activeEvents,
153 161 'author' => $authorProfile,
@@ -153,17 +161,18 @@
153 161 'author' => $authorProfile,
154 162 'title' => $calendar->title .' - '.get_bloginfo('name'),
155 163 'description' => $metaDescription,
156 164 'url' => home_url($wp->request),
165 + 'embedded' => isset($_GET['embedded']) ? true : false, // phpcs:ignore WordPress.Security.NonceVerification.Recommended
157 166 'css_files' => [
158 - App::getInstance('url.assets') . 'public/saas.css'
167 + Vite::styleUrl('saas_css')
159 168 ],
160 169 'js_files' => [
161 - 'fluent-booking-public-js' => $assetUrl . 'public/js/app.js',
170 + 'fluent-booking-public-js' => Vite::scriptUrl('public_app'),
162 171 ],
163 172 'js_vars' => $jsVars,
164 173 'header_js_files' => [
165 - 'fluent_booking_team_app-js' => $assetUrl. 'public/js/team_app.js'
174 + 'fluent_booking_team_app-js' => Vite::scriptUrl('team_app')
166 175 ]
167 176 ];
168 177
169 178 if ($extraJsFiles) {
@@ -171,9 +180,9 @@
171 180 $data['js_files'] = array_merge($data['js_files'], $extraJsFiles);
172 181 }
173 182
174 183 $data = apply_filters('fluent_booking/host_view_page_vars', $data, $calendar, $activeEvents, $authorProfile);
175 -
184 +
176 185 $app = App::getInstance();
177 186 status_header(200);
178 187 $app->view->render('landing.author_landing', $data);
179 188 exit(200);
@@ -178,14 +187,16 @@
178 187 $app->view->render('landing.author_landing', $data);
179 188 exit(200);
180 189 }
181 190
182 - private function renderBookingView($calendar, $calendarEvent, $existingBooking = null)
191 + private function renderBookingView($calendar, $calendarEvent, $existingBooking = null, $isReschedule = false)
183 192 {
184 - $settings = LandingPageHelper::getSettings($calendar, 'public');
185 - if ($settings['show_type'] != 'all') {
186 - if (!in_array($calendarEvent->id, $settings['enabled_slots'])) {
187 - return '';
193 + if (!$isReschedule) {
194 + $settings = LandingPageHelper::getSettings($calendar, 'public');
195 + if ($settings['show_type'] != 'all') {
196 + if (!in_array($calendarEvent->id, $settings['enabled_slots'])) {
197 + return '';
198 + }
188 199 }
189 200 }
190 201
191 202 global $wp;
@@ -193,9 +204,9 @@
193 204 $calendarEvent->max_lookup_date = $calendarEvent->getMaxLookUpDate();
194 205 $calendarEvent->min_lookup_date = $calendarEvent->getMinLookUpDate();
195 206
196 207 if (!empty($_REQUEST['booking_id'])) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended
197 - $bookingHash = sanitize_text_field($_REQUEST['booking_id']); // phpcs:ignore WordPress.Security.NonceVerification.Recommended
208 + $bookingHash = sanitize_text_field(wp_unslash($_REQUEST['booking_id'])); // phpcs:ignore WordPress.Security.NonceVerification.Recommended
198 209 $booking = Booking::where('hash', $bookingHash)
199 210 ->where('event_id', $calendarEvent->id)
200 211 ->first();
201 212 if ($booking) {
@@ -217,24 +228,27 @@
217 228 $assetUrl = App::getInstance('url.assets');
218 229
219 230 $eventVars = (new FrontEndHandler())->getCalendarEventVars($calendar, $calendarEvent);
220 231
221 - $isRtl = Helper::fluentbooking_is_rtl();
232 + $publicCss = 'saas_css';
222 233
223 - $publicCss = $isRtl ? 'public/saas-rtl.css' : 'public/saas.css';
234 + $title = $calendarEvent->title . ' ' . __('with', 'fluent-booking') . ' ' . $authorProfile['name'];
224 235
236 + $title = apply_filters('fluent_booking/booking_confirmation_page_title', $title, $calendarEvent, $authorProfile);
237 +
225 238 $data = [
226 239 'calendar' => $calendar,
227 240 'calendar_event' => $calendarEvent,
228 241 'author' => $authorProfile,
229 - 'title' => $calendarEvent->title . ' ' . __('with', 'fluent-booking') . ' ' . $authorProfile['name'],
242 + 'title' => $title,
230 243 'description' => substr(strip_shortcodes(wp_strip_all_tags(str_replace(PHP_EOL, ' ', $calendarEvent->description))), 0, 300) . '...',
231 244 'url' => home_url($wp->request),
245 + 'embedded' => isset($_GET['embedded']) ? true : false, // phpcs:ignore WordPress.Security.NonceVerification.Recommended
232 246 'css_files' => [
233 - $assetUrl . $publicCss
247 + Vite::styleUrl($publicCss)
234 248 ],
235 249 'js_files' => [
236 - 'fluent-booking-public-js' => $assetUrl . 'public/js/app.js',
250 + 'fluent-booking-public-js' => Vite::scriptUrl('public_app'),
237 251 ],
238 252 'js_vars' => [
239 253 'fluentCalendarPublicVars' => (new FrontEndHandler())->getGlobalVars(),
240 254 'fcal_public_vars_' . $calendar->id . '_' . $calendarEvent->id => $eventVars,
@@ -268,9 +282,8 @@
268 282
269 283 private function showBookingConfimationPage($booking, $actionType = 'confirmation')
270 284 {
271 285 $validActions = ['confirmation'];
272 - $isRtl = Helper::fluentbooking_is_rtl();
273 286
274 287 if (in_array($booking->status, ['scheduled', 'pending', 'rescheduled'])) {
275 288 $validActions = array_merge($validActions, ['reschedule', 'cancel']);
276 289 }
@@ -291,24 +304,24 @@
291 304 echo $icsText; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
292 305 die();
293 306 }
294 307
308 + global $wp;
309 +
295 310 $calendarEvent = $booking->calendar_event;
296 - global $wp;
311 +
297 312 $responseHtml = BookingService::getBookingConfirmationHtml($booking, $actionType);
298 313
299 314 $authorProfile = $calendarEvent->getAuthorProfile(true);
300 315
301 - $publicCss = 'public/saas_public.css';
302 - if ($isRtl) {
303 - $publicCss = 'public/saas_public-rtl.css';
304 - }
316 + $publicCss = 'saas_public_css';
317 +
305 318 $data = [
306 319 'title' => __('Confirmation: ', 'fluent-booking') . $calendarEvent->title . ' ' . __('with', 'fluent-booking') . ' ' . $authorProfile['name'],
307 320 'body' => $responseHtml,
308 321 'description' => substr(strip_shortcodes(wp_strip_all_tags(str_replace(PHP_EOL, ' ', $calendarEvent->description))), 0, 300) . '...',
309 322 'css_files' => [
310 - App::getInstance('url.assets') . $publicCss
323 + Vite::styleUrl($publicCss)
311 324 ],
312 325 'js_files' => [],
313 326 'js_vars' => [],
314 327 'author' => $authorProfile,
@@ -314,15 +327,23 @@
314 327 'author' => $authorProfile,
315 328 'slot' => $calendarEvent,
316 329 'url' => home_url($wp->request),
317 330 'action_type' => $actionType,
318 - 'theme' => Arr::get(get_option('_fluent_booking_settings'), 'theme','system-default')
331 + 'embedded' => isset($_GET['embedded']) ? true : false, // phpcs:ignore WordPress.Security.NonceVerification.Recommended
332 + 'theme' => Arr::get(get_option('_fluent_booking_settings'), 'theme','system-default'),
333 + 'back_button' => [
334 + 'show' => true,
335 + 'text' => __('Back to home', 'fluent-booking'),
336 + 'url' => site_url('/')
337 + ]
319 338 ];
320 339
321 340 if ($actionType == 'cancel') {
322 - $data['js_files']['fluent-booking-public-manage-meeting-js'] = App::getInstance('url.assets') . 'public/js/public-manage-meeting.js';
341 + $data['js_files']['fluent-booking-public-manage-meeting-js'] = Vite::scriptUrl('manage_meeting');
323 342 }
324 343
344 + $data = apply_filters('fluent_booking/booking_confirmation_page_vars', $data, $booking, $calendarEvent);
345 +
325 346 $app = App::getInstance();
326 347 status_header(200);
327 348 $app->view->render('landing.confirmation_page', $data);
328 349 exit(200);
@@ -329,21 +350,20 @@
329 350 }
330 351
331 352 private function handleAfterBookingPage()
332 353 {
333 - $bookingHash = sanitize_text_field(Arr::get($_REQUEST, 'meeting_hash')); // phpcs:ignore WordPress.Security.NonceVerification.Recommended
334 -
354 + $bookingHash = sanitize_text_field(wp_unslash(Arr::get($_REQUEST, 'meeting_hash'))); // phpcs:ignore WordPress.Security.NonceVerification.Recommended
335 355 if (!$bookingHash) {
336 356 return;
337 357 }
338 358
339 359 $booking = Booking::where('hash', $bookingHash)->first();
340 -
341 360 if (!$booking) {
342 361 return;
343 362 }
344 363
345 364 $type = Arr::get($_REQUEST, 'type', 'confirmation'); // phpcs:ignore WordPress.Security.NonceVerification.Recommended
365 +
346 366 $this->showBookingConfimationPage($booking, $type);
347 367 }
348 368
349 369 private function handleRescheduleView(Booking $booking)
@@ -411,11 +431,29 @@
411 431 </style>
412 432 <?php
413 433 });
414 434
415 - $this->renderBookingView($booking->calendar, $booking->calendar_event, $booking);
435 + $this->renderBookingView($booking->calendar, $booking->calendar_event, $booking, true);
416 436 }
417 437
438 + private function handleEmbeddedStyle()
439 + {
440 + add_action('wp_print_styles', function () {
441 + global $wp_styles;
442 + if($wp_styles) {
443 + foreach ($wp_styles->queue as $style) {
444 + $src = $wp_styles->registered[$style]->src;
445 + if (
446 + (strpos($src, 'fluentbooking') === false) &&
447 + (strpos($src, 'fluent_booking') === false)
448 + ) {
449 + wp_dequeue_style($wp_styles->registered[$style]->handle);
450 + }
451 + }
452 + }
453 + }, 100);
454 + }
455 +
418 456 public function getEventLandingExtraJsFiles($formFields, $calendarEvent)
419 457 {
420 458 $files = [];
421 459 $assetUrl = App::getInstance('url.assets');
@@ -420,9 +458,9 @@
420 458 $files = [];
421 459 $assetUrl = App::getInstance('url.assets');
422 460
423 461 if (BookingFieldService::hasPhoneNumberField($formFields)) {
424 - $files['fluent-booking-phone-field-js'] = $assetUrl . 'public/js/phone-field.js';
462 + $files['fluent-booking-phone-field-js'] = Vite::scriptUrl('phone_field');
425 463 }
426 464
427 465 if ($calendarEvent->type == 'paid') {
428 466 $files['fluent-booking-checkout-sdk-stripe-js'] = 'https://js.stripe.com/v3/';