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
fluent-booking / app / Hooks / Handlers / BlockEditorHandler.php

BlockEditorHandler.php in Fluent Booking – The Ultimate Appointments Scheduling, Events Booking, Events Calendar Solution 2.5.0, at app/Hooks/Handlers/BlockEditorHandler.php

406 lines 14.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace FluentBooking\App\Hooks\Handlers;
4
5 use FluentBooking\App\App;
6 use FluentBooking\App\Vite;
7 use FluentBooking\App\Models\Calendar;
8 use FluentBooking\App\Models\CalendarSlot;
9 use FluentBooking\App\Services\CalendarEventService;
10 use FluentBooking\App\Services\Helper;
11 use FluentBooking\App\Services\LocationService;
12 use FluentBooking\Framework\Support\Arr;
13
14 class BlockEditorHandler
15 {
16 public function init()
17 {
18 add_action('enqueue_block_editor_assets', function () {
19 $blockDeps = array('wp-blocks', 'wp-components', 'wp-block-editor', 'wp-element');
20
21 $assetsVersion = Vite::isDev() ? time() : FLUENT_BOOKING_ASSETS_VERSION;
22
23 Vite::enqueueScript('fluent-booking/calendar', 'fb_index', $blockDeps, $assetsVersion);
24
25 wp_localize_script('fluent-booking/calendar', 'fluentCalendarGutenbergVars', [
26 'ajaxurl' => admin_url('admin-ajax.php'),
27 ]);
28
29 Vite::enqueueScript('fluent-booking/team-management', 'fb_team', $blockDeps, $assetsVersion);
30
31 Vite::enqueueScript('fluent-booking/calendar-management', 'fb_calendar', $blockDeps, $assetsVersion);
32
33 Vite::enqueueScript('fluent-booking/booking-management', 'fb_booking', $blockDeps, $assetsVersion);
34
35 $calendars = Calendar::with(['metas', 'events' => function ($query) {
36 $query->where('status', 'active');
37 }])->where('status', 'active')->get();
38
39 $formattedCalendars = [];
40
41 foreach ($calendars as $calendar) {
42 if ($calendar->events->isEmpty()) {
43 continue;
44 }
45
46 $formattedEvents = [];
47 foreach ($calendar->events as $event) {
48 $formattedEvents[] = [
49 'id' => (string)$event->id,
50 'title' => $event->title,
51 'color_schema' => $event->color_schema,
52 'durations' => $event->getAvailableDurations(),
53 'locations' => $event->defaultLocationHtml(),
54 'payment_html' => $event->getPaymentHtml(),
55 'loc_settings' => LocationService::sanitizePublicLocationSettings($event->location_settings),
56 'description' => $event->short_description
57 ];
58 }
59
60 $formattedCalendars[$calendar->id] = [
61 'id' => (string)$calendar->id,
62 'title' => $calendar->title,
63 'description' => wpautop(Helper::excerpt($calendar->description, 200)),
64 'author' => Arr::only($calendar->getAuthorProfile(), ['name', 'avatar']),
65 'event_order' => $calendar->getMeta('event_order'),
66 'events' => $formattedEvents
67 ];
68 }
69
70 wp_localize_script('fluent-booking/calendar', 'fluent_booking_block', [
71 'assets_url' => App::getInstance()['url.assets'] ?? '',
72 'hosts' => $formattedCalendars
73 ]);
74 });
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
89 register_block_type('fluent-booking/calendar', array(
90 'editor_script' => 'fluent-booking/calendar',
91 'render_callback' => array($this, 'fcalRenderBlock'),
92 'attributes' => [
93 'slotId' => [
94 'type' => 'string',
95 'default' => '',
96 ],
97 'calendarId' => [
98 'type' => 'string',
99 'default' => '',
100 ],
101 'eventHash' => [
102 'type' => 'string',
103 'default' => '',
104 ],
105 'avatar_rounded' => [
106 'type' => 'boolean',
107 'default' => false
108 ],
109 'primary_color' => [
110 'type' => 'string',
111 'default' => '#4587EC'
112 ],
113 'date_round' => [
114 'type' => 'string',
115 'default' => '4px'
116 ],
117 'avatarStyle' => [
118 'type' => 'string',
119 'default' => '8px'
120 ],
121 'hideHostInfo' => [
122 'type' => 'string',
123 'default' => 'no'
124 ],
125 'theme' => [
126 'type' => 'string',
127 'default' => 'light'
128 ]
129 ]
130 ));
131
132 register_block_type('fluent-booking/team-management', array(
133 'editor_script' => 'fluent-booking/team-management',
134 'render_callback' => array($this, 'fcalRenderTeamManagementBlock'),
135 'attributes' => [
136 'title' => [
137 'type' => 'string',
138 'default' => ''
139 ],
140 'description' => [
141 'type' => 'string',
142 'default' => ''
143 ],
144 'headerImage' => [
145 'type' => 'object',
146 'default' => ''
147 ],
148 'hosts' => [
149 'type' => 'object',
150 'default' => ''
151 ]
152 ]
153 ));
154
155 register_block_type('fluent-booking/calendar-management', array(
156 'editor_script' => 'fluent-booking/calendar-management',
157 'render_callback' => array($this, 'fcalRenderCalendarManagementBlock'),
158 'attributes' => array(
159 'title' => array(
160 'type' => 'string',
161 'default' => ''
162 ),
163 'description' => array(
164 'type' => 'string',
165 'default' => ''
166 ),
167 'headerImage' => array(
168 'type' => 'object',
169 'default' => ''
170 ),
171 'calendarId' => array(
172 'type' => 'string',
173 'default' => ''
174 ),
175 'eventIds' => array(
176 'type' => 'array',
177 'default' => []
178 ),
179 'hideInfo' => array(
180 'type' => 'boolean',
181 'default' => false
182 )
183 )
184 ));
185
186 register_block_type('fluent-booking/booking-management', array(
187 'editor_script' => 'fluent-booking/booking-management',
188 'render_callback' => array($this, 'fcalRenderBookingManagementBlock'),
189 'attributes' => [
190 'title' => [
191 'type' => 'string',
192 'default' => __('My Bookings', 'fluent-booking')
193 ],
194 'showFilter' => [
195 'type' => 'boolean',
196 'default' => true
197 ],
198 'showPagination' => [
199 'type' => 'boolean',
200 'default' => true
201 ],
202 'period' => [
203 'type' => 'string',
204 'default' => 'all'
205 ],
206 'perPage' => [
207 'type' => 'number',
208 'default' => 5
209 ],
210 'noBookingsMessage' => [
211 'type' => 'string',
212 'default' => __('No bookings found', 'fluent-booking')
213 ],
214 'calendarIds' => [
215 'type' => 'array',
216 'default' => ['all']
217 ]
218 ]
219 ));
220 }
221
222 public function fcalRenderTeamManagementBlock($attributes)
223 {
224 $hosts = Arr::get($attributes, 'calendarHosts', []);
225
226 $wrapperClassName = Arr::get($attributes, 'className');
227
228 if (!$hosts) {
229 return '';
230 }
231
232 $hostItems = [];
233
234 foreach ($hosts as $config) {
235 $calendar = Calendar::with('metas')->find($config['id']);
236 if (!$calendar) {
237 continue;
238 }
239
240 $eventIds = Arr::get($config, 'events', []);
241 if (!$eventIds) {
242 continue;
243 }
244
245 $eventsQuery = CalendarSlot::where('calendar_id', $calendar->id)
246 ->where('status', 'active');
247
248 if (!in_array('all', $eventIds)) {
249 $eventsQuery->whereIn('id', $eventIds);
250 }
251
252 $events = $eventsQuery->get();
253
254 if ($events->isEmpty()) {
255 continue;
256 }
257
258 $events = CalendarEventService::processEvents($calendar, $events);
259
260 $calendar->activeEvents = $events;
261
262 $hostItems[$calendar->id] = $calendar;
263 }
264
265 return (new FrontEndHandler())->renderTeamHosts($hostItems, [
266 'title' => Arr::get($attributes, 'title'),
267 'description' => Arr::get($attributes, 'description'),
268 'logo' => Arr::get($attributes, 'headerImage.url'),
269 'wrapper_class' => $wrapperClassName
270 ]);
271 }
272
273 public function fcalRenderCalendarManagementBlock($attributes)
274 {
275 $calendarId = Arr::get($attributes, 'calendarId');
276
277 $eventIds = Arr::get($attributes, 'eventIds', []);
278
279 if (!$calendarId || !$eventIds) {
280 return '';
281 }
282
283 $calendar = Calendar::find($calendarId);
284 if (!$calendar) {
285 return '';
286 }
287
288 $eventsQuery = CalendarSlot::where('calendar_id', $calendar->id)
289 ->where('status', 'active');
290
291 if (!in_array('all', $eventIds)) {
292 $eventsQuery->whereIn('id', $eventIds);
293 }
294
295 $events = $eventsQuery->get();
296
297 if ($events->isEmpty()) {
298 return '';
299 }
300
301 $events = CalendarEventService::processEvents($calendar, $events);
302
303 $calendar->activeEvents = $events;
304
305 return (new FrontEndHandler())->renderCalendarBlock($calendar, [
306 'title' => Arr::get($attributes, 'title'),
307 'description' => Arr::get($attributes, 'description'),
308 'wrapper_class' => Arr::get($attributes, 'className'),
309 'logo' => Arr::get($attributes, 'headerImage.url'),
310 'hide_info' => Arr::isTrue($attributes, 'hideInfo')
311 ]);
312 }
313
314 public function fcalRenderBookingManagementBlock($attributes)
315 {
316 $calendarIds = (array) Arr::get($attributes, 'calendarIds', []);
317
318 if (!$calendarIds || in_array('all', $calendarIds, true)) {
319 $calendarIds = 'all';
320 } else {
321 $calendarIds = implode(',', array_map('intval', $calendarIds));
322 }
323
324 $title = sanitize_text_field(Arr::get($attributes, 'title'));
325
326 $period = sanitize_key(Arr::get($attributes, 'period', 'all'));
327
328 $perPage = intval(Arr::get($attributes, 'perPage', 10));
329
330 $showFilter = Arr::isTrue($attributes, 'showFilter', true) ? 'show' : 'hide';
331
332 $showPagination = Arr::isTrue($attributes, 'showPagination', true) ? 'show' : 'hide';
333
334 $noBookingsMessage = sanitize_text_field(Arr::get($attributes, 'noBookingsMessage'));
335
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);
348 }
349
350 public function fcalRenderBlock($attributes)
351 {
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', ''));
355
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>';
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
374 $slot = CalendarSlot::find($slotId);
375
376 if (!$slot) {
377 $slot = CalendarSlot::where('hash', $eventHash)->first();
378 if (!$slot) {
379 return '';
380 }
381 $slotId = (int) $slot->id;
382 $eventHash = (string) $slot->hash;
383 }
384
385 $output .= '<div class="fluent-booking-calendar-block align' . esc_attr($align) . '">';
386
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 ));
394
395 $output .= '</div>';
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 : '';
404 }
405 }
406