PluginProbe
Fluent Booking – The Ultimate Appointments Scheduling, Events Booking, Events Calendar Solution / trunk
Fluent Booking – The Ultimate Appointments Scheduling, Events Booking, Events Calendar Solution vtrunk
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
← All changes | app/Services/EditorShortCodeParser.php +106 -30 1.5.23trunk View file →
@@ -28,9 +28,9 @@
28 28 static::setData($booking);
29 29 return static::parseShortCodes($parsable);
30 30 } catch (\Exception $e) {
31 31 if (defined('WP_DEBUG') && WP_DEBUG) {
32 - error_log($e->getTraceAsString());
32 + error_log($e->getTraceAsString()); // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log
33 33 }
34 34 return '';
35 35 }
36 36 }
@@ -88,30 +88,50 @@
88 88 if ($key == 'full_start_and_end_host_timezone') {
89 89 return $booking->getFullBookingDateTimeText($booking->getHostTimezone()) . ' (' . $booking->getHostTimezone() . ')';
90 90 }
91 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 +
92 108 if ($key == 'start_date_time') {
93 109 return $booking->start_time;
94 110 }
95 111
96 - if ($key == 'start_date_time_for_attendee') {
97 - return DateTimeHelper::convertFromUtc($booking->start_time, $booking->person_time_zone, 'Y-m-d H:i:s');
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));
98 116 }
99 117
100 - if ($key == 'start_date_time_for_host') {
101 - return DateTimeHelper::convertFromUtc($booking->start_time, $booking->getHostTimezone(), 'Y-m-d H:i:s');
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));
102 122 }
103 123
104 124 if ($key == 'cancel_reason') {
105 - return $booking->getCancelReason(true);
125 + return $booking->getCancelReason(false, true);
106 126 }
107 127
108 128 if ($key == 'reject_reason') {
109 - return $booking->getRejectReason(true);
129 + return $booking->getRejectReason(false, true);
110 130 }
111 131
112 132 if ($key == 'reschedule_reason') {
113 - return $booking->getRescheduleReason();
133 + return $booking->getRescheduleReason(true);
114 134 }
115 135
116 136 if ($key == 'previous_meeting_time') {
117 137 return $booking->getPreviousMeetingTime($booking->getHostTimezone()) . ' (' . $booking->getHostTimezone() . ')';
@@ -116,8 +136,20 @@
116 136 if ($key == 'previous_meeting_time') {
117 137 return $booking->getPreviousMeetingTime($booking->getHostTimezone()) . ' (' . $booking->getHostTimezone() . ')';
118 138 }
119 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 +
120 152 if ($key == 'start_time_human_format') {
121 153 if (time() > strtotime($booking->start_time)) {
122 154 $suffix = __(' ago', 'fluent-booking');
123 155 } else {
@@ -182,11 +214,14 @@
182 214 self::$store['custom_booking_data'] = $booking->getMeta('custom_fields_data', []);
183 215 }
184 216
185 217 if (self::$store['custom_booking_data']) {
186 - if (preg_match('/format\.([a-zA-Z\-]+)/', $key, $matches)) {
187 - $value = Arr::get(self::$store['custom_booking_data'], preg_split('/\.format\./', $key)[0]);
188 - return gmdate($matches[1], strtotime($value)); // phpcs:ignore WordPress.DateTime.RestrictedFunctions.date_date
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)) : '';
189 224 }
190 225
191 226 $customField = BookingFieldService::getBookingFieldByName($booking->calendar_event, $key);
192 227
@@ -193,8 +228,25 @@
193 228 if (Arr::get($customField, 'type') == 'file') {
194 229 return self::getUploadedFileUrl(Arr::get(self::$store['custom_booking_data'], $key));
195 230 }
196 231
232 + if (Arr::get($customField, 'type') == 'hidden') {
233 + static $resolving = [];
234 +
235 + // Guest-supplied hidden values are parsed again, so a self-reference would recurse until the stack runs out.
236 + if (isset($resolving[$key])) {
237 + return Arr::get(self::$store['custom_booking_data'], $key);
238 + }
239 +
240 + $resolving[$key] = true;
241 +
242 + try {
243 + return self::parseShortCodes(Arr::get(self::$store['custom_booking_data'], $key));
244 + } finally {
245 + unset($resolving[$key]);
246 + }
247 + }
248 +
197 249 return Arr::get(self::$store['custom_booking_data'], $key);
198 250 }
199 251
200 252 return '';
@@ -209,9 +261,9 @@
209 261 }
210 262
211 263 if ($key == 'timezone') {
212 264 $booking = static::$store['booking'];
213 - return $booking->getHostTimezone();
265 + return $booking ? $booking->getHostTimezone() : null;
214 266 }
215 267
216 268 return Arr::get($host, $key, '');
217 269 }
@@ -239,20 +291,23 @@
239 291 if ('full_name' == $key) {
240 292 return $guest['first_name'] . ' ' . $guest['last_name'];
241 293 }
242 294 if ('timezone' == $key) {
243 - $booking = static::$store['booking'];
244 - return $booking->person_time_zone;
295 + return $guest->person_time_zone;
245 296 }
246 297 if ('note' == $key) {
247 298 return $guest->getMessage();
248 299 }
249 300
301 + if ($key == 'total_guest') {
302 + return $guest->getTotalGuestCount();
303 + }
304 +
250 305 if ($key == 'form_data_html') {
251 306 return __('will be available soon', 'fluent-booking');
252 307 }
253 308
254 - return Arr::get($guest, $key, '');
309 + return self::resolveScalarAttribute($guest, $key);
255 310 }
256 311
257 312 protected static function getBookingEventData($key)
258 313 {
@@ -267,9 +322,9 @@
267 322 if (in_array($key, $fillables)) {
268 323 return $bookingEvent->{$key};
269 324 }
270 325
271 - return '';
326 + return self::resolveScalarAttribute($bookingEvent, $key);
272 327 }
273 328
274 329 protected static function getCalendarData($key)
275 330 {
@@ -284,11 +339,26 @@
284 339 if (in_array($key, $fillables)) {
285 340 return $calendar->{$key};
286 341 }
287 342
288 - return '';
343 + return self::resolveScalarAttribute($calendar, $key);
289 344 }
290 345
346 + /**
347 + * Resolve a scalar attribute only; never a relation (dumps as JSON) or a
348 + * dotted hop into a relation's columns.
349 + */
350 + protected static function resolveScalarAttribute($model, $key)
351 + {
352 + if (strpos($key, '.') !== false) {
353 + return '';
354 + }
355 +
356 + $value = isset($model[$key]) ? $model[$key] : '';
357 +
358 + return is_scalar($value) ? $value : '';
359 + }
360 +
291 361 protected static function getPaymentData($key)
292 362 {
293 363 $booking = static::$store['booking'];
294 364
@@ -309,9 +379,9 @@
309 379 }
310 380
311 381 $order = static::$store['payment_order'];
312 382
313 - if ($key == 'payment_total') {
383 + if ($key == 'payment_total' && $order) {
314 384 $isZeroDecimal = CurrenciesHelper::isZeroDecimal($order->currency);
315 385 if ($isZeroDecimal) {
316 386 return $order->total_amount;
317 387 } else {
@@ -323,23 +393,23 @@
323 393 return apply_filters('fluent_booking/payment_receipt_html', '', $booking->hash);
324 394 }
325 395
326 396 if ($key == 'payment_status') {
327 - return $order->status;
397 + return $order ? $order->status : '';
328 398 }
329 399
330 400 if ($key == 'payment_currency') {
331 - return $order->currency;
401 + return $order ? $order->currency : '';
332 402 }
333 403
334 404 if ($key == 'payment_date') {
335 - return $order->created_at;
405 + return $order ? $order->created_at : '';
336 406 }
337 407
338 408 $fillables = (new \FluentBookingPro\App\Models\Order())->getFillable();
339 409
340 410 if (in_array($key, $fillables)) {
341 - return $order->{$key};
411 + return $order ? $order->{$key} : '';
342 412 }
343 413
344 414 return '';
345 415 }
@@ -345,12 +415,13 @@
345 415 }
346 416
347 417 protected static function getUserData($key)
348 418 {
349 - if (is_null(static::$store['user'])) {
350 - static::$store['user'] = wp_get_current_user();
419 + $user = static::$store['user'];
420 + if (is_null($user)) {
421 + $user = wp_get_current_user();
351 422 }
352 - return static::$store['user']->{$key};
423 + return $user ? $user->{$key} : '';
353 424 }
354 425
355 426 protected static function getWPData($key)
356 427 {
@@ -367,9 +438,14 @@
367 438 }
368 439
369 440 protected static function getOtherData($key)
370 441 {
371 - self::$store['meeting_bookmarks'] ??= static::$store['booking']->getMeetingBookmarks();
442 + $meetingBookmarks = self::$store['meeting_bookmarks'];
443 + if (!$meetingBookmarks) {
444 + $booking = static::$store['booking'];
445 + $meetingBookmarks = $booking ? $booking->getMeetingBookmarks() : null;
446 + self::$store['meeting_bookmarks'] = $meetingBookmarks;
447 + }
372 448
373 449 if (0 === strpos($key, 'date.')) {
374 450 $format = str_replace('date.', '', $key);
375 451 return gmdate($format, strtotime(current_time('mysql'))); // phpcs:ignore WordPress.DateTime.RestrictedFunctions.date_date
@@ -375,15 +451,15 @@
375 451 return gmdate($format, strtotime(current_time('mysql'))); // phpcs:ignore WordPress.DateTime.RestrictedFunctions.date_date
376 452 } elseif ('add_booking_to_calendar' === $key) {
377 453 return static::parseShortCodes(Helper::getAddToCalendarHtml());
378 454 } elseif ('add_to_g_calendar_url' === $key) {
379 - return Arr::get(self::$store['meeting_bookmarks'], 'google.url');
455 + return Arr::get($meetingBookmarks, 'google.url');
380 456 } elseif ('add_to_ol_calendar_url' === $key) {
381 - return Arr::get(self::$store['meeting_bookmarks'], 'outlook.url');
457 + return Arr::get($meetingBookmarks, 'outlook.url');
382 458 } elseif ('add_to_ms_calendar_url' === $key) {
383 - return Arr::get(self::$store['meeting_bookmarks'], 'msoffice.url');
459 + return Arr::get($meetingBookmarks, 'msoffice.url');
384 460 } elseif ('add_to_ics_calendar_url' === $key) {
385 - return Arr::get(self::$store['meeting_bookmarks'], 'other.url');
461 + return Arr::get($meetingBookmarks, 'other.url');
386 462 }
387 463
388 464 return $key;
389 465 }