PluginProbe
Fluent Booking – The Ultimate Appointments Scheduling, Events Booking, Events Calendar Solution / 1.10.0
Fluent Booking – The Ultimate Appointments Scheduling, Events Booking, Events Calendar Solution v1.10.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 1.7.2 All 33 releases
fluent-booking / app / Services / EditorShortCodeParser.php

EditorShortCodeParser.php in Fluent Booking – The Ultimate Appointments Scheduling, Events Booking, Events Calendar Solution 1.10.0, at app/Services/EditorShortCodeParser.php

509 lines 16.5 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\Services;
4
5 use FluentBooking\App\Models\Booking;
6 use FluentBooking\App\Models\Calendar;
7 use FluentBooking\App\Models\CalendarSlot;
8 use FluentBooking\Framework\Support\Arr;
9
10 class EditorShortCodeParser
11 {
12 protected static $requireHtml = true;
13
14 protected static $store = [
15 'booking' => null,
16 'calendar_booking' => null,
17 'calendar' => null,
18 'host' => null,
19 'user' => null,
20 'custom_booking_data' => null,
21 'payment_order' => null
22 ];
23
24 public static function parse($parsable, $booking, $requireHtml = true)
25 {
26 try {
27 static::$requireHtml = $requireHtml;
28 static::setData($booking);
29 return static::parseShortCodes($parsable);
30 } catch (\Exception $e) {
31 if (defined('WP_DEBUG') && WP_DEBUG) {
32 error_log($e->getTraceAsString()); // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log
33 }
34 return '';
35 }
36 }
37
38 protected static function setData($booking)
39 {
40 static::$store['booking'] = $booking;
41 static::$store['booking_event'] = $booking->calendar_event;
42 static::$store['calendar'] = $booking->calendar;
43 static::$store['host'] = $booking->getHostDetails(false);
44 static::$store['team_members'] = $booking->getHostsDetails(false, $booking->host_user_id);
45 static::$store['custom_booking_data'] = null;
46 static::$store['payment_order'] = null;
47 static::$store['meeting_bookmarks'] = null;
48 }
49
50 protected static function getBookingData($key)
51 {
52 $bookingEvent = static::$store['booking_event'];
53 $calendar = static::$store['calendar'];
54 $booking = static::$store['booking'];
55
56 if (!$bookingEvent || !$calendar || !$booking) {
57 return '';
58 }
59
60 if ($key == 'event_name') {
61 return $bookingEvent->title;
62 }
63
64 if ($key == 'description') {
65 return $bookingEvent->description;
66 }
67
68 if ($key == 'booking_title') {
69 return $booking->getBookingTitle();
70 }
71
72 if ($key == 'additional_guests') {
73 return $booking->getAdditionalGuests(true);
74 }
75
76 if ($key == 'full_start_end_guest_timezone') {
77 return $booking->getShortBookingDateTime($booking->person_time_zone) . ' (' . $booking->person_time_zone . ')';
78 }
79
80 if ($key == 'full_start_end_host_timezone') {
81 return $booking->getShortBookingDateTime($booking->getHostTimezone()) . ' (' . $booking->getHostTimezone() . ')';
82 }
83
84 if ($key == 'full_start_and_end_guest_timezone') {
85 return $booking->getFullBookingDateTimeText($booking->person_time_zone) . ' (' . $booking->person_time_zone . ')';
86 }
87
88 if ($key == 'full_start_and_end_host_timezone') {
89 return $booking->getFullBookingDateTimeText($booking->getHostTimezone()) . ' (' . $booking->getHostTimezone() . ')';
90 }
91
92 if ($key == 'start_date_time') {
93 return $booking->start_time;
94 }
95
96 if (str_starts_with($key, 'start_date_time_for_attendee')) {
97 $format = preg_match('/format\.([a-zA-Z\-: ]+)/', $key, $matches) ? $matches[1] : 'Y-m-d H:i:s';
98 $dateTime = DateTimeHelper::convertFromUtc($booking->start_time, $booking->person_time_zone, 'Y-m-d H:i:s');
99 return date_i18n($format, strtotime($dateTime));
100 }
101
102 if (str_starts_with($key, 'start_date_time_for_host')) {
103 $format = preg_match('/format\.([a-zA-Z\-: ]+)/', $key, $matches) ? $matches[1] : 'Y-m-d H:i:s';
104 $dateTime = DateTimeHelper::convertFromUtc($booking->start_time, $booking->getHostTimezone(), 'Y-m-d H:i:s');
105 return date_i18n($format, strtotime($dateTime));
106 }
107
108 if ($key == 'cancel_reason') {
109 return $booking->getCancelReason(false, true);
110 }
111
112 if ($key == 'reject_reason') {
113 return $booking->getRejectReason(false, true);
114 }
115
116 if ($key == 'reschedule_reason') {
117 return $booking->getRescheduleReason(true);
118 }
119
120 if ($key == 'previous_meeting_time') {
121 return $booking->getPreviousMeetingTime($booking->getHostTimezone()) . ' (' . $booking->getHostTimezone() . ')';
122 }
123
124 if ($key == 'previous_meeting_time_guest_timezone') {
125 return $booking->getPreviousMeetingTime($booking->person_time_zone) . ' (' . $booking->person_time_zone . ')';
126 }
127
128 if ($key == 'previous_meeting_date_time_host_timezone') {
129 return $booking->getPreviousMeetingDateTimeText($booking->getHostTimezone()) . ' (' . $booking->getHostTimezone() . ')';
130 }
131
132 if ($key == 'previous_meeting_date_time_guest_timezone') {
133 return $booking->getPreviousMeetingDateTimeText($booking->person_time_zone) . ' (' . $booking->person_time_zone . ')';
134 }
135
136 if ($key == 'start_time_human_format') {
137 if (time() > strtotime($booking->start_time)) {
138 $suffix = __(' ago', 'fluent-booking');
139 } else {
140 $suffix = __(' from now', 'fluent-booking');
141 }
142
143 return human_time_diff(time(), strtotime($booking->start_time)) . ' ' . $suffix;
144 }
145
146 if ($key == 'cancelation_url') {
147 return $booking->getCancelUrl();
148 }
149
150 if ($key == 'reschedule_url') {
151 return $booking->getRescheduleUrl();
152 }
153
154 if ($key == 'admin_booking_url') {
155 return Helper::getAdminBookingUrl($booking->id) . '&period=upcoming';
156 }
157
158 if ($key == 'booking_confirm_url') {
159 return Helper::getAdminBookingUrl($booking->id) . '&period=pending&confirm_booking=true';
160 }
161
162 if ($key == 'booking_reject_url') {
163 return Helper::getAdminBookingUrl($booking->id) . '&period=pending&reject_booking=true';
164 }
165
166 if ($key == 'location_details_html') {
167 return $booking->getLocationDetailsHtml();
168 }
169
170 if ($key == 'location_details_text') {
171 return $booking->getLocationAsText();
172 }
173
174 if ($key == 'booking_hash') {
175 return $booking->hash;
176 }
177
178 $fillables = (new Booking())->getFillable();
179 $fillables[] = 'id';
180 $fillables[] = 'created_at';
181 $fillables[] = 'updated_at';
182
183 if (in_array($key, $fillables)) {
184 return $booking->{$key};
185 }
186
187 return '';
188 }
189
190 protected static function getBookingCustomData($key)
191 {
192 $booking = static::$store['booking'];
193 if (!$booking) {
194 return '';
195 }
196
197 if (self::$store['custom_booking_data'] === null) {
198 self::$store['custom_booking_data'] = $booking->getMeta('custom_fields_data', []);
199 }
200
201 if (self::$store['custom_booking_data']) {
202 if (preg_match('/format\.([a-zA-Z\-: ]+)/', $key, $matches)) {
203 $fieldKey = preg_split('/\.format\./', $key)[0];
204 $value = Arr::get(self::$store['custom_booking_data'], $fieldKey);
205 $customField = BookingFieldService::getBookingFieldByName($booking->calendar_event, $fieldKey);
206 $formattedDate = DateTimeHelper::getFormattedDate($value, Arr::get($customField, 'date_format'));
207 return $formattedDate ? date_i18n($matches[1], strtotime($formattedDate)) : '';
208 }
209
210 $customField = BookingFieldService::getBookingFieldByName($booking->calendar_event, $key);
211
212 if (Arr::get($customField, 'type') == 'file') {
213 return self::getUploadedFileUrl(Arr::get(self::$store['custom_booking_data'], $key));
214 }
215
216 if (Arr::get($customField, 'type') == 'hidden') {
217 return self::parseShortCodes(Arr::get(self::$store['custom_booking_data'], $key));
218 }
219
220 return Arr::get(self::$store['custom_booking_data'], $key);
221 }
222
223 return '';
224 }
225
226 protected static function getHostData($key)
227 {
228 $host = static::$store['host'];
229
230 if (is_null($host)) {
231 return '';
232 }
233
234 if ($key == 'timezone') {
235 $booking = static::$store['booking'];
236 return $booking ? $booking->getHostTimezone() : null;
237 }
238
239 return Arr::get($host, $key, '');
240 }
241
242 protected static function getTeamMembersData($key)
243 {
244 $teamMembers = static::$store['team_members'];
245
246 if (empty($teamMembers)) {
247 return '';
248 }
249
250 list($key, $value) = explode('.', $key);
251
252 return Arr::get($teamMembers, $key - 1 . '.' . $value, '');
253 }
254
255 protected static function getGuestData($key)
256 {
257 $guest = static::$store['booking'];
258 if (is_null($guest)) {
259 return '';
260 }
261
262 if ('full_name' == $key) {
263 return $guest['first_name'] . ' ' . $guest['last_name'];
264 }
265 if ('timezone' == $key) {
266 return $guest->person_time_zone;
267 }
268 if ('note' == $key) {
269 return $guest->getMessage();
270 }
271
272 if ($key == 'total_guest') {
273 return $guest->getTotalGuestCount();
274 }
275
276 if ($key == 'form_data_html') {
277 return __('will be available soon', 'fluent-booking');
278 }
279
280 return Arr::get($guest, $key, '');
281 }
282
283 protected static function getBookingEventData($key)
284 {
285 $bookingEvent = static::$store['booking_event'];
286
287 if (is_null($bookingEvent)) {
288 return '';
289 }
290
291 $fillables = (new CalendarSlot())->getFillable();
292
293 if (in_array($key, $fillables) || isset($bookingEvent->{$key})) {
294 return $bookingEvent->{$key};
295 }
296
297 return '';
298 }
299
300 protected static function getCalendarData($key)
301 {
302 $calendar = static::$store['calendar'];
303
304 if (is_null($calendar)) {
305 return '';
306 }
307
308 $fillables = (new Calendar())->getFillable();
309
310 if (in_array($key, $fillables) || isset($calendar->{$key})) {
311 return $calendar->{$key};
312 }
313
314 return '';
315 }
316
317 protected static function getPaymentData($key)
318 {
319 $booking = static::$store['booking'];
320
321 if (is_null($booking)) {
322 return '';
323 }
324
325 if (!$booking->payment_status) {
326 return '';
327 }
328
329 if (is_null(static::$store['payment_order'])) {
330 static::$store['payment_order'] = $booking->payment_order;
331 }
332
333 if (!static::$store['payment_order']) {
334 return '';
335 }
336
337 $order = static::$store['payment_order'];
338
339 if ($key == 'payment_total' && $order) {
340 $isZeroDecimal = CurrenciesHelper::isZeroDecimal($order->currency);
341 if ($isZeroDecimal) {
342 return $order->total_amount;
343 } else {
344 return $order->total_amount / 100;
345 }
346 }
347
348 if ($key == 'receipt_html') {
349 return apply_filters('fluent_booking/payment_receipt_html', '', $booking->hash);
350 }
351
352 if ($key == 'payment_status') {
353 return $order ? $order->status : '';
354 }
355
356 if ($key == 'payment_currency') {
357 return $order ? $order->currency : '';
358 }
359
360 if ($key == 'payment_date') {
361 return $order ? $order->created_at : '';
362 }
363
364 $fillables = (new \FluentBookingPro\App\Models\Order())->getFillable();
365
366 if (in_array($key, $fillables)) {
367 return $order ? $order->{$key} : '';
368 }
369
370 return '';
371 }
372
373 protected static function getUserData($key)
374 {
375 $user = static::$store['user'];
376 if (is_null($user)) {
377 $user = wp_get_current_user();
378 }
379 return $user ? $user->{$key} : '';
380 }
381
382 protected static function getWPData($key)
383 {
384 if ('site_url' == $key) {
385 return site_url();
386 }
387 if ('admin_email' == $key) {
388 return get_option('admin_email');
389 }
390 if ('site_title' == $key) {
391 return get_option('blogname');
392 }
393 return $key;
394 }
395
396 protected static function getOtherData($key)
397 {
398 $meetingBookmarks = self::$store['meeting_bookmarks'];
399 if (!$meetingBookmarks) {
400 $booking = static::$store['booking'];
401 $meetingBookmarks = $booking ? $booking->getMeetingBookmarks() : null;
402 self::$store['meeting_bookmarks'] = $meetingBookmarks;
403 }
404
405 if (0 === strpos($key, 'date.')) {
406 $format = str_replace('date.', '', $key);
407 return gmdate($format, strtotime(current_time('mysql'))); // phpcs:ignore WordPress.DateTime.RestrictedFunctions.date_date
408 } elseif ('add_booking_to_calendar' === $key) {
409 return static::parseShortCodes(Helper::getAddToCalendarHtml());
410 } elseif ('add_to_g_calendar_url' === $key) {
411 return Arr::get($meetingBookmarks, 'google.url');
412 } elseif ('add_to_ol_calendar_url' === $key) {
413 return Arr::get($meetingBookmarks, 'outlook.url');
414 } elseif ('add_to_ms_calendar_url' === $key) {
415 return Arr::get($meetingBookmarks, 'msoffice.url');
416 } elseif ('add_to_ics_calendar_url' === $key) {
417 return Arr::get($meetingBookmarks, 'other.url');
418 }
419
420 return $key;
421 }
422
423 protected static function getUploadedFileUrl($fieldValue)
424 {
425 if (empty($fieldValue)) {
426 return '';
427 }
428
429 $files = array_map(function($file) {
430 return '<a href="' . esc_url($file) . '" style="color:#222;font-size:15px;" target="_blank" download="' . esc_attr(basename($file)) . '">' . esc_html(basename($file)) . '</a>';
431 }, $fieldValue);
432
433 return '<ul><li>' . implode('</li><li>', $files) . '</li></ul>';
434 }
435
436 protected static function parseShortCodes($parsable)
437 {
438 if (is_array($parsable)) {
439 return static::parseFromArray($parsable);
440 }
441
442 return static::parseFromString($parsable);
443 }
444
445 protected static function parseFromArray($parsable)
446 {
447 foreach ($parsable as $key => $value) {
448 if (is_array($value)) {
449 $parsable[$key] = static::parseFromArray($value);
450 } else {
451 $parsable[$key] = static::parseFromString($value);
452 }
453 }
454
455 return $parsable;
456 }
457
458 protected static function parseFromString($parsable)
459 {
460 if (!$parsable) {
461 return '';
462 }
463
464 return preg_replace_callback('/({{|##)+(.*?)(}}|##)/', function ($matches) {
465 $value = '';
466
467 if (empty($matches[2])) {
468 return '';
469 }
470
471 $match = $matches[2];
472
473 if (false !== strpos($match, 'guest.')) {
474 $guestProperty = substr($match, strlen('guest.'));
475 $value = static::getGuestData($guestProperty);
476 } elseif (false !== strpos($match, 'booking.custom.')) {
477 $customBookingProp = substr($match, strlen('booking.custom.'));
478 $value = static::getBookingCustomData($customBookingProp);
479 } elseif (false !== strpos($match, 'booking.')) {
480 $bookingProperty = substr($match, strlen('booking.'));
481 $value = static::getBookingData($bookingProperty);
482 } elseif (false !== strpos($match, 'host.')) {
483 $hostProperty = substr($match, strlen('host.'));
484 $value = static::getHostData($hostProperty);
485 } elseif (false !== strpos($match, 'team_member.')) {
486 $teamMemberProperty = substr($match, strlen('team_member.'));
487 $value = static::getTeamMembersData($teamMemberProperty);
488 } elseif (false !== strpos($match, 'event.')) {
489 $eventProperty = substr($match, strlen('event.'));
490 $value = static::getBookingEventData($eventProperty);
491 } elseif (false !== strpos($match, 'calendar.')) {
492 $calendarProperty = substr($match, strlen('calendar.'));
493 $value = static::getCalendarData($calendarProperty);
494 } elseif (false !== strpos($match, 'payment.')) {
495 $paymentProperty = substr($match, strlen('payment.'));
496 $value = static::getPaymentData($paymentProperty);
497 } else {
498 $value = static::getOtherData($match);
499 }
500
501 if (static::$requireHtml && is_array($value)) {
502 $value = Helper::fcalImplodeRecursive(', ', $value);
503 }
504
505 return $value;
506 }, $parsable);
507 }
508 }
509