PluginProbe
Fluent Booking – The Ultimate Appointments Scheduling, Events Booking, Events Calendar Solution / 2.2.5
Fluent Booking – The Ultimate Appointments Scheduling, Events Booking, Events Calendar Solution v2.2.5
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 1.7.2 All 33 releases
fluent-booking / app / Hooks / Handlers / BlockEditorHandler.php

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

405 lines 14.3 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\Framework\Support\Arr;
12
13 class BlockEditorHandler
14 {
15 public function init()
16 {
17 add_action('enqueue_block_editor_assets', function () {
18 $blockDeps = array('wp-blocks', 'wp-components', 'wp-block-editor', 'wp-element');
19
20 $assetsVersion = Vite::isDev() ? time() : FLUENT_BOOKING_ASSETS_VERSION;
21
22 Vite::enqueueScript('fluent-booking/calendar', 'fb_index', $blockDeps, $assetsVersion);
23
24 wp_localize_script('fluent-booking/calendar', 'fluentCalendarGutenbergVars', [
25 'ajaxurl' => admin_url('admin-ajax.php'),
26 ]);
27
28 Vite::enqueueScript('fluent-booking/team-management', 'fb_team', $blockDeps, $assetsVersion);
29
30 Vite::enqueueScript('fluent-booking/calendar-management', 'fb_calendar', $blockDeps, $assetsVersion);
31
32 Vite::enqueueScript('fluent-booking/booking-management', 'fb_booking', $blockDeps, $assetsVersion);
33
34 $calendars = Calendar::with(['metas', 'events' => function ($query) {
35 $query->where('status', 'active');
36 }])->where('status', 'active')->get();
37
38 $formattedCalendars = [];
39
40 foreach ($calendars as $calendar) {
41 if ($calendar->events->isEmpty()) {
42 continue;
43 }
44
45 $formattedEvents = [];
46 foreach ($calendar->events as $event) {
47 $formattedEvents[] = [
48 'id' => (string)$event->id,
49 'title' => $event->title,
50 'color_schema' => $event->color_schema,
51 'durations' => $event->getAvailableDurations(),
52 'locations' => $event->defaultLocationHtml(),
53 'payment_html' => $event->getPaymentHtml(),
54 'loc_settings' => $event->location_settings,
55 'description' => $event->short_description
56 ];
57 }
58
59 $formattedCalendars[$calendar->id] = [
60 'id' => (string)$calendar->id,
61 'title' => $calendar->title,
62 'description' => wpautop(Helper::excerpt($calendar->description, 200)),
63 'author' => $calendar->getAuthorProfile(),
64 'event_order' => $calendar->getMeta('event_order'),
65 'events' => $formattedEvents
66 ];
67 }
68
69 wp_localize_script('fluent-booking/calendar', 'fluent_booking_block', [
70 'assets_url' => App::getInstance()['url.assets'] ?? '',
71 'hosts' => $formattedCalendars
72 ]);
73 });
74
75 add_action('enqueue_block_assets', function () {
76 if (!is_admin()) {
77 return;
78 }
79
80 $assetsVersion = Vite::isDev() ? time() : FLUENT_BOOKING_ASSETS_VERSION;
81
82 Vite::enqueueStyle('fluent-booking/calendar-style', 'fb_index_css', [], $assetsVersion);
83 Vite::enqueueStyle('fluent-booking/team-management-style', 'fb_team_css', [], $assetsVersion);
84 Vite::enqueueStyle('fluent-booking/calendar-management-style', 'fb_calendar_css', [], $assetsVersion);
85 Vite::enqueueStyle('fluent-booking/booking-management-style', 'fb_booking_css', [], $assetsVersion);
86 });
87
88 register_block_type('fluent-booking/calendar', array(
89 'editor_script' => 'fluent-booking/calendar',
90 'render_callback' => array($this, 'fcalRenderBlock'),
91 'attributes' => [
92 'slotId' => [
93 'type' => 'string',
94 'default' => '',
95 ],
96 'calendarId' => [
97 'type' => 'string',
98 'default' => '',
99 ],
100 'eventHash' => [
101 'type' => 'string',
102 'default' => '',
103 ],
104 'avatar_rounded' => [
105 'type' => 'boolean',
106 'default' => false
107 ],
108 'primary_color' => [
109 'type' => 'string',
110 'default' => '#4587EC'
111 ],
112 'date_round' => [
113 'type' => 'string',
114 'default' => '4px'
115 ],
116 'avatarStyle' => [
117 'type' => 'string',
118 'default' => '8px'
119 ],
120 'hideHostInfo' => [
121 'type' => 'string',
122 'default' => 'no'
123 ],
124 'theme' => [
125 'type' => 'string',
126 'default' => 'light'
127 ]
128 ]
129 ));
130
131 register_block_type('fluent-booking/team-management', array(
132 'editor_script' => 'fluent-booking/team-management',
133 'render_callback' => array($this, 'fcalRenderTeamManagementBlock'),
134 'attributes' => [
135 'title' => [
136 'type' => 'string',
137 'default' => ''
138 ],
139 'description' => [
140 'type' => 'string',
141 'default' => ''
142 ],
143 'headerImage' => [
144 'type' => 'object',
145 'default' => ''
146 ],
147 'hosts' => [
148 'type' => 'object',
149 'default' => ''
150 ]
151 ]
152 ));
153
154 register_block_type('fluent-booking/calendar-management', array(
155 'editor_script' => 'fluent-booking/calendar-management',
156 'render_callback' => array($this, 'fcalRenderCalendarManagementBlock'),
157 'attributes' => array(
158 'title' => array(
159 'type' => 'string',
160 'default' => ''
161 ),
162 'description' => array(
163 'type' => 'string',
164 'default' => ''
165 ),
166 'headerImage' => array(
167 'type' => 'object',
168 'default' => ''
169 ),
170 'calendarId' => array(
171 'type' => 'string',
172 'default' => ''
173 ),
174 'eventIds' => array(
175 'type' => 'array',
176 'default' => []
177 ),
178 'hideInfo' => array(
179 'type' => 'boolean',
180 'default' => false
181 )
182 )
183 ));
184
185 register_block_type('fluent-booking/booking-management', array(
186 'editor_script' => 'fluent-booking/booking-management',
187 'render_callback' => array($this, 'fcalRenderBookingManagementBlock'),
188 'attributes' => [
189 'title' => [
190 'type' => 'string',
191 'default' => __('My Bookings', 'fluent-booking')
192 ],
193 'showFilter' => [
194 'type' => 'boolean',
195 'default' => true
196 ],
197 'showPagination' => [
198 'type' => 'boolean',
199 'default' => true
200 ],
201 'period' => [
202 'type' => 'string',
203 'default' => 'all'
204 ],
205 'perPage' => [
206 'type' => 'number',
207 'default' => 5
208 ],
209 'noBookingsMessage' => [
210 'type' => 'string',
211 'default' => __('No bookings found', 'fluent-booking')
212 ],
213 'calendarIds' => [
214 'type' => 'array',
215 'default' => ['all']
216 ]
217 ]
218 ));
219 }
220
221 public function fcalRenderTeamManagementBlock($attributes)
222 {
223 $hosts = Arr::get($attributes, 'calendarHosts', []);
224
225 $wrapperClassName = Arr::get($attributes, 'className');
226
227 if (!$hosts) {
228 return '';
229 }
230
231 $hostItems = [];
232
233 foreach ($hosts as $config) {
234 $calendar = Calendar::with('metas')->find($config['id']);
235 if (!$calendar) {
236 continue;
237 }
238
239 $eventIds = Arr::get($config, 'events', []);
240 if (!$eventIds) {
241 continue;
242 }
243
244 $eventsQuery = CalendarSlot::where('calendar_id', $calendar->id)
245 ->where('status', 'active');
246
247 if (!in_array('all', $eventIds)) {
248 $eventsQuery->whereIn('id', $eventIds);
249 }
250
251 $events = $eventsQuery->get();
252
253 if ($events->isEmpty()) {
254 continue;
255 }
256
257 $events = CalendarEventService::processEvents($calendar, $events);
258
259 $calendar->activeEvents = $events;
260
261 $hostItems[$calendar->id] = $calendar;
262 }
263
264 return (new FrontEndHandler())->renderTeamHosts($hostItems, [
265 'title' => Arr::get($attributes, 'title'),
266 'description' => Arr::get($attributes, 'description'),
267 'logo' => Arr::get($attributes, 'headerImage.url'),
268 'wrapper_class' => $wrapperClassName
269 ]);
270 }
271
272 public function fcalRenderCalendarManagementBlock($attributes)
273 {
274 $calendarId = Arr::get($attributes, 'calendarId');
275
276 $eventIds = Arr::get($attributes, 'eventIds', []);
277
278 if (!$calendarId || !$eventIds) {
279 return '';
280 }
281
282 $calendar = Calendar::find($calendarId);
283 if (!$calendar) {
284 return '';
285 }
286
287 $eventsQuery = CalendarSlot::where('calendar_id', $calendar->id)
288 ->where('status', 'active');
289
290 if (!in_array('all', $eventIds)) {
291 $eventsQuery->whereIn('id', $eventIds);
292 }
293
294 $events = $eventsQuery->get();
295
296 if ($events->isEmpty()) {
297 return '';
298 }
299
300 $events = CalendarEventService::processEvents($calendar, $events);
301
302 $calendar->activeEvents = $events;
303
304 return (new FrontEndHandler())->renderCalendarBlock($calendar, [
305 'title' => Arr::get($attributes, 'title'),
306 'description' => Arr::get($attributes, 'description'),
307 'wrapper_class' => Arr::get($attributes, 'className'),
308 'logo' => Arr::get($attributes, 'headerImage.url'),
309 'hide_info' => Arr::isTrue($attributes, 'hideInfo')
310 ]);
311 }
312
313 public function fcalRenderBookingManagementBlock($attributes)
314 {
315 $calendarIds = (array) Arr::get($attributes, 'calendarIds', []);
316
317 if (!$calendarIds || in_array('all', $calendarIds, true)) {
318 $calendarIds = 'all';
319 } else {
320 $calendarIds = implode(',', array_map('intval', $calendarIds));
321 }
322
323 $title = sanitize_text_field(Arr::get($attributes, 'title'));
324
325 $period = sanitize_key(Arr::get($attributes, 'period', 'all'));
326
327 $perPage = intval(Arr::get($attributes, 'perPage', 10));
328
329 $showFilter = Arr::isTrue($attributes, 'showFilter', true) ? 'show' : 'hide';
330
331 $showPagination = Arr::isTrue($attributes, 'showPagination', true) ? 'show' : 'hide';
332
333 $noBookingsMessage = sanitize_text_field(Arr::get($attributes, 'noBookingsMessage'));
334
335 $shortcode = sprintf(
336 '[fluent_booking_lists title="%s" period=%s per_page=%d filter=%s pagination=%s no_bookings="%s" calendar_ids=%s]',
337 esc_attr($title),
338 $period,
339 $perPage,
340 $showFilter,
341 $showPagination,
342 esc_attr($noBookingsMessage),
343 $calendarIds
344 );
345
346 return do_shortcode($shortcode);
347 }
348
349 public function fcalRenderBlock($attributes)
350 {
351 $primaryColor = sanitize_hex_color(Arr::get($attributes, 'primary_color', ''));
352 $dateRadius = self::sanitizeCssLength(Arr::get($attributes, 'date_round', ''));
353 $avatarRadius = self::sanitizeCssLength(Arr::get($attributes, 'avatarStyle', ''));
354
355 $output = '<style>:root {';
356 if ($primaryColor) {
357 $output .= '--fcal_primary_color: ' . $primaryColor . ' !important;';
358 }
359 if ($dateRadius) {
360 $output .= '--fcal_date_radius: ' . $dateRadius . ' !important;';
361 }
362 if ($avatarRadius) {
363 $output .= '--fcal_avatar_radius: ' . $avatarRadius . ' !important;';
364 }
365 $output .= '}</style>';
366
367 $slotId = (int) Arr::get($attributes, 'slotId');
368 $disableHost = Arr::isTrue($attributes, 'hideHostInfo') ? 'yes' : 'no';
369 $theme = sanitize_key(Arr::get($attributes, 'theme', 'light'));
370 $eventHash = sanitize_text_field(Arr::get($attributes, 'eventHash', ''));
371 $align = sanitize_html_class(Arr::get($attributes, 'align', ''));
372
373 $slot = CalendarSlot::find($slotId);
374
375 if (!$slot) {
376 $slot = CalendarSlot::where('hash', $eventHash)->first();
377 if (!$slot) {
378 return '';
379 }
380 $slotId = (int) $slot->id;
381 $eventHash = (string) $slot->hash;
382 }
383
384 $output .= '<div class="fluent-booking-calendar-block align' . esc_attr($align) . '">';
385
386 $output .= do_shortcode(sprintf(
387 '[fluent_booking id=%d disable_author=%s theme=%s hash=%s]',
388 $slotId,
389 $disableHost,
390 $theme,
391 esc_attr($eventHash)
392 ));
393
394 $output .= '</div>';
395 return $output;
396 }
397
398 private static function sanitizeCssLength($value)
399 {
400 $value = trim((string) $value);
401
402 return preg_match('/^\d{1,3}(\.\d+)?(px|%|em|rem)$/', $value) ? $value : '';
403 }
404 }
405