PluginProbe
Fluent Booking – The Ultimate Appointments Scheduling, Events Booking, Events Calendar Solution / 2.2.0
Fluent Booking – The Ultimate Appointments Scheduling, Events Booking, Events Calendar Solution v2.2.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 2.2.0, at app/Services/EditorShortCodeParser.php

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