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/Hooks/Handlers/BlockEditorHandler.php +89 -90 1.5.20 → 2.5.0 View file →
@@ -2,11 +2,14 @@
2 2
3 3 namespace FluentBooking\App\Hooks\Handlers;
4 4
5 5 use FluentBooking\App\App;
6 +use FluentBooking\App\Vite;
6 7 use FluentBooking\App\Models\Calendar;
7 8 use FluentBooking\App\Models\CalendarSlot;
9 +use FluentBooking\App\Services\CalendarEventService;
8 10 use FluentBooking\App\Services\Helper;
11 +use FluentBooking\App\Services\LocationService;
9 12 use FluentBooking\Framework\Support\Arr;
10 13
11 14 class BlockEditorHandler
12 15 {
@@ -12,48 +15,25 @@
12 15 {
13 16 public function init()
14 17 {
15 18 add_action('enqueue_block_editor_assets', function () {
16 - $app = App::getInstance();
17 - $assets = $app['url.assets'];
19 + $blockDeps = array('wp-blocks', 'wp-components', 'wp-block-editor', 'wp-element');
18 20
19 - wp_enqueue_script(
20 - 'fluent-booking/calendar',
21 - $assets . 'admin/fluent-booking-index.js',
22 - array('wp-blocks', 'wp-components', 'wp-block-editor', 'wp-element'),
23 - FLUENT_BOOKING_ASSETS_VERSION,
24 - true
25 - );
21 + $assetsVersion = Vite::isDev() ? time() : FLUENT_BOOKING_ASSETS_VERSION;
26 22
23 + Vite::enqueueScript('fluent-booking/calendar', 'fb_index', $blockDeps, $assetsVersion);
24 +
27 25 wp_localize_script('fluent-booking/calendar', 'fluentCalendarGutenbergVars', [
28 26 'ajaxurl' => admin_url('admin-ajax.php'),
29 27 ]);
30 28
31 - wp_enqueue_script(
32 - 'fluent-booking/team-management',
33 - $assets . 'admin/fluent-booking-team-management-index.js',
34 - array('wp-blocks', 'wp-components', 'wp-block-editor', 'wp-element'),
35 - FLUENT_BOOKING_ASSETS_VERSION,
36 - true
37 - );
29 + Vite::enqueueScript('fluent-booking/team-management', 'fb_team', $blockDeps, $assetsVersion);
38 30
39 - wp_enqueue_script(
40 - 'fluent-booking/calendar-management',
41 - $assets . 'admin/fluent-booking-calendar-management-index.js',
42 - array('wp-blocks', 'wp-components', 'wp-block-editor', 'wp-element'),
43 - FLUENT_BOOKING_ASSETS_VERSION,
44 - true
45 - );
31 + Vite::enqueueScript('fluent-booking/calendar-management', 'fb_calendar', $blockDeps, $assetsVersion);
46 32
47 - wp_enqueue_script(
48 - 'fluent-booking/booking-management',
49 - $assets . 'admin/fluent-booking-booking-management-index.js',
50 - array('wp-blocks', 'wp-components', 'wp-block-editor', 'wp-element'),
51 - FLUENT_BOOKING_ASSETS_VERSION,
52 - true
53 - );
33 + Vite::enqueueScript('fluent-booking/booking-management', 'fb_booking', $blockDeps, $assetsVersion);
54 34
55 - $calendars = Calendar::with(['events' => function ($query) {
35 + $calendars = Calendar::with(['metas', 'events' => function ($query) {
56 36 $query->where('status', 'active');
57 37 }])->where('status', 'active')->get();
58 38
59 39 $formattedCalendars = [];
@@ -71,10 +51,10 @@
71 51 'color_schema' => $event->color_schema,
72 52 'durations' => $event->getAvailableDurations(),
73 53 'locations' => $event->defaultLocationHtml(),
74 54 'payment_html' => $event->getPaymentHtml(),
75 - 'loc_settings' => $event->location_settings,
76 - 'description' => Helper::excerpt($event->getDescription())
55 + 'loc_settings' => LocationService::sanitizePublicLocationSettings($event->location_settings),
56 + 'description' => $event->short_description
77 57 ];
78 58 }
79 59
80 60 $formattedCalendars[$calendar->id] = [
@@ -80,9 +60,9 @@
80 60 $formattedCalendars[$calendar->id] = [
81 61 'id' => (string)$calendar->id,
82 62 'title' => $calendar->title,
83 63 'description' => wpautop(Helper::excerpt($calendar->description, 200)),
84 - 'author' => $calendar->getAuthorProfile(),
64 + 'author' => Arr::only($calendar->getAuthorProfile(), ['name', 'avatar']),
85 65 'event_order' => $calendar->getMeta('event_order'),
86 66 'events' => $formattedEvents
87 67 ];
88 68 }
@@ -87,13 +67,26 @@
87 67 ];
88 68 }
89 69
90 70 wp_localize_script('fluent-booking/calendar', 'fluent_booking_block', [
91 - 'assets_url' => $assets,
71 + 'assets_url' => App::getInstance()['url.assets'] ?? '',
92 72 'hosts' => $formattedCalendars
93 73 ]);
94 74 });
95 75
76 + add_action('enqueue_block_assets', function () {
77 + if (!is_admin()) {
78 + return;
79 + }
80 +
81 + $assetsVersion = Vite::isDev() ? time() : FLUENT_BOOKING_ASSETS_VERSION;
82 +
83 + Vite::enqueueStyle('fluent-booking/calendar-style', 'fb_index_css', [], $assetsVersion);
84 + Vite::enqueueStyle('fluent-booking/team-management-style', 'fb_team_css', [], $assetsVersion);
85 + Vite::enqueueStyle('fluent-booking/calendar-management-style', 'fb_calendar_css', [], $assetsVersion);
86 + Vite::enqueueStyle('fluent-booking/booking-management-style', 'fb_booking_css', [], $assetsVersion);
87 + });
88 +
96 89 register_block_type('fluent-booking/calendar', array(
97 90 'editor_script' => 'fluent-booking/calendar',
98 91 'render_callback' => array($this, 'fcalRenderBlock'),
99 92 'attributes' => [
@@ -238,9 +231,9 @@
238 231
239 232 $hostItems = [];
240 233
241 234 foreach ($hosts as $config) {
242 - $calendar = Calendar::find($config['id']);
235 + $calendar = Calendar::with('metas')->find($config['id']);
243 236 if (!$calendar) {
244 237 continue;
245 238 }
246 239
@@ -261,25 +254,10 @@
261 254 if ($events->isEmpty()) {
262 255 continue;
263 256 }
264 257
265 - $eventOrder = $calendar->getMeta('event_order');
258 + $events = CalendarEventService::processEvents($calendar, $events);
266 259
267 - if (!empty($eventOrder)) {
268 - $events = $events->sortBy(function ($event) use ($eventOrder) {
269 - return array_search($event->id, $eventOrder);
270 - })->values();
271 - }
272 -
273 - foreach ($events as $event) {
274 - $event->payment_html = $event->getPaymentHtml();
275 - $event->public_url = $event->getPublicUrl();
276 - $event->durations = $event->getAvailableDurations();
277 - $event->description = $event->getDescription();
278 - $event->short_description = Helper::excerpt($event->description);
279 - $event->locations = $event->defaultLocationHtml();
280 - }
281 -
282 260 $calendar->activeEvents = $events;
283 261
284 262 $hostItems[$calendar->id] = $calendar;
285 263 }
@@ -319,25 +297,10 @@
319 297 if ($events->isEmpty()) {
320 298 return '';
321 299 }
322 300
323 - $eventOrder = $calendar->getMeta('event_order');
301 + $events = CalendarEventService::processEvents($calendar, $events);
324 302
325 - if (!empty($eventOrder)) {
326 - $events = $events->sortBy(function ($event) use ($eventOrder) {
327 - return array_search($event->id, $eventOrder);
328 - })->values();
329 - }
330 -
331 - foreach ($events as $event) {
332 - $event->payment_html = $event->getPaymentHtml();
333 - $event->public_url = $event->getPublicUrl();
334 - $event->durations = $event->getAvailableDurations();
335 - $event->description = $event->getDescription();
336 - $event->short_description = Helper::excerpt($event->description);
337 - $event->locations = $event->defaultLocationHtml();
338 - }
339 -
340 303 $calendar->activeEvents = $events;
341 304
342 305 return (new FrontEndHandler())->renderCalendarBlock($calendar, [
343 306 'title' => Arr::get($attributes, 'title'),
@@ -349,13 +312,19 @@
349 312 }
350 313
351 314 public function fcalRenderBookingManagementBlock($attributes)
352 315 {
353 - $calendarIds = Arr::get($attributes, 'calendarIds', []);
316 + $calendarIds = (array) Arr::get($attributes, 'calendarIds', []);
354 317
318 + if (!$calendarIds || in_array('all', $calendarIds, true)) {
319 + $calendarIds = 'all';
320 + } else {
321 + $calendarIds = implode(',', array_map('intval', $calendarIds));
322 + }
323 +
355 324 $title = sanitize_text_field(Arr::get($attributes, 'title'));
356 325
357 - $period = sanitize_text_field(Arr::get($attributes, 'period', 'all'));
326 + $period = sanitize_key(Arr::get($attributes, 'period', 'all'));
358 327
359 328 $perPage = intval(Arr::get($attributes, 'perPage', 10));
360 329
361 330 $showFilter = Arr::isTrue($attributes, 'showFilter', true) ? 'show' : 'hide';
@@ -363,44 +332,74 @@
363 332 $showPagination = Arr::isTrue($attributes, 'showPagination', true) ? 'show' : 'hide';
364 333
365 334 $noBookingsMessage = sanitize_text_field(Arr::get($attributes, 'noBookingsMessage'));
366 335
367 - return do_shortcode("[fluent_booking_lists title=\"$title\" period=$period per_page=$perPage filter=$showFilter pagination=$showPagination no_bookings=\"$noBookingsMessage\" calendar_ids=" . implode(',', $calendarIds) . "]");
336 + $shortcode = sprintf(
337 + '[fluent_booking_lists title="%s" period=%s per_page=%d filter=%s pagination=%s no_bookings="%s" calendar_ids=%s]',
338 + esc_attr($title),
339 + $period,
340 + $perPage,
341 + $showFilter,
342 + $showPagination,
343 + esc_attr($noBookingsMessage),
344 + $calendarIds
345 + );
346 +
347 + return do_shortcode($shortcode);
368 348 }
369 349
370 350 public function fcalRenderBlock($attributes)
371 351 {
372 - $output = '<style>
373 - :root {
374 - --fcal_primary_color: ' . esc_attr($attributes['primary_color']) . ' !important;
375 - --fcal_date_radius: ' . esc_attr($attributes['date_round']) . ' !important;
376 - --fcal_avatar_radius: ' . esc_attr($attributes['avatarStyle']) . ' !important;
377 - }
378 - </style>';
352 + $primaryColor = sanitize_hex_color(Arr::get($attributes, 'primary_color', ''));
353 + $dateRadius = self::sanitizeCssLength(Arr::get($attributes, 'date_round', ''));
354 + $avatarRadius = self::sanitizeCssLength(Arr::get($attributes, 'avatarStyle', ''));
379 355
380 - $slotId = (int) $attributes['slotId'];
381 - $disableHost = $attributes['hideHostInfo'];
382 - $theme = Arr::get($attributes, 'theme', 'light');
356 + $output = '<style>:root {';
357 + if ($primaryColor) {
358 + $output .= '--fcal_primary_color: ' . $primaryColor . ' !important;';
359 + }
360 + if ($dateRadius) {
361 + $output .= '--fcal_date_radius: ' . $dateRadius . ' !important;';
362 + }
363 + if ($avatarRadius) {
364 + $output .= '--fcal_avatar_radius: ' . $avatarRadius . ' !important;';
365 + }
366 + $output .= '}</style>';
383 367
368 + $slotId = (int) Arr::get($attributes, 'slotId');
369 + $disableHost = Arr::isTrue($attributes, 'hideHostInfo') ? 'yes' : 'no';
370 + $theme = sanitize_key(Arr::get($attributes, 'theme', 'light'));
371 + $eventHash = sanitize_text_field(Arr::get($attributes, 'eventHash', ''));
372 + $align = sanitize_html_class(Arr::get($attributes, 'align', ''));
373 +
384 374 $slot = CalendarSlot::find($slotId);
385 375
386 376 if (!$slot) {
387 - $eventHash = Arr::get($attributes, 'eventHash');
388 - if ($eventHash) {
389 - $slot = CalendarSlot::where('hash', $eventHash)->first();
390 - }
377 + $slot = CalendarSlot::where('hash', $eventHash)->first();
391 378 if (!$slot) {
392 379 return '';
393 380 }
394 -
395 - $slotId = $slot->id;
381 + $slotId = (int) $slot->id;
382 + $eventHash = (string) $slot->hash;
396 383 }
397 384
385 + $output .= '<div class="fluent-booking-calendar-block align' . esc_attr($align) . '">';
398 386
399 - $output .= '<div class="fluent-booking-calendar-block align' . Arr::get($attributes, 'align') . '">';
387 + $output .= do_shortcode(sprintf(
388 + '[fluent_booking id=%d disable_author=%s theme=%s hash=%s]',
389 + $slotId,
390 + $disableHost,
391 + $theme,
392 + esc_attr($eventHash)
393 + ));
400 394
401 - $output .= do_shortcode("[fluent_booking id=$slotId disable_author=$disableHost theme=$theme]");
402 -
403 395 $output .= '</div>';
404 396 return $output;
397 + }
398 +
399 + private static function sanitizeCssLength($value)
400 + {
401 + $value = trim((string) $value);
402 +
403 + return preg_match('/^\d{1,3}(\.\d+)?(px|%|em|rem)$/', $value) ? $value : '';
405 404 }
406 405 }