null,
'calendar_booking' => null,
'calendar' => null,
'host' => null,
'user' => null,
'custom_booking_data' => null,
'payment_order' => null
];
public static function parse($parsable, $booking, $requireHtml = true)
{
try {
static::$requireHtml = $requireHtml;
static::setData($booking);
return static::parseShortCodes($parsable);
} catch (\Exception $e) {
if (defined('WP_DEBUG') && WP_DEBUG) {
error_log($e->getTraceAsString()); // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log
}
return '';
}
}
protected static function setData($booking)
{
static::$store['booking'] = $booking;
static::$store['booking_event'] = $booking->calendar_event;
static::$store['calendar'] = $booking->calendar;
static::$store['host'] = $booking->getHostDetails(false);
static::$store['team_members'] = $booking->getHostsDetails(false, $booking->host_user_id);
static::$store['custom_booking_data'] = null;
static::$store['payment_order'] = null;
static::$store['meeting_bookmarks'] = null;
}
protected static function getBookingData($key)
{
$bookingEvent = static::$store['booking_event'];
$calendar = static::$store['calendar'];
$booking = static::$store['booking'];
if (!$bookingEvent || !$calendar || !$booking) {
return '';
}
if ($key == 'event_name') {
return $bookingEvent->title;
}
if ($key == 'description') {
return $bookingEvent->description;
}
if ($key == 'booking_title') {
return $booking->getBookingTitle();
}
if ($key == 'additional_guests') {
return $booking->getAdditionalGuests(true);
}
if ($key == 'full_start_end_guest_timezone') {
return $booking->getShortBookingDateTime($booking->person_time_zone) . ' (' . $booking->person_time_zone . ')';
}
if ($key == 'full_start_end_host_timezone') {
return $booking->getShortBookingDateTime($booking->getHostTimezone()) . ' (' . $booking->getHostTimezone() . ')';
}
if ($key == 'full_start_and_end_guest_timezone') {
return $booking->getFullBookingDateTimeText($booking->person_time_zone) . ' (' . $booking->person_time_zone . ')';
}
if ($key == 'full_start_and_end_host_timezone') {
return $booking->getFullBookingDateTimeText($booking->getHostTimezone()) . ' (' . $booking->getHostTimezone() . ')';
}
if ($key == 'all_bookings_short_times_guest_timezone') {
return implode("
", $booking->getAllBookingShortTimes($booking->person_time_zone, true));
}
if ($key == 'all_bookings_short_times_host_timezone') {
return implode("
", $booking->getAllBookingShortTimes($booking->getHostTimezone(), true));
}
if ($key == 'all_bookings_full_times_guest_timezone') {
return implode("
", $booking->getAllBookingFullTimes($booking->person_time_zone, true));
}
if ($key == 'all_bookings_full_times_host_timezone') {
return implode("
", $booking->getAllBookingFullTimes($booking->getHostTimezone(), true));
}
if ($key == 'start_date_time') {
return $booking->start_time;
}
if (strpos($key, 'start_date_time_for_attendee') === 0) {
$format = preg_match('/format\.([a-zA-Z\-: ]+)/', $key, $matches) ? $matches[1] : 'Y-m-d H:i:s';
$dateTime = DateTimeHelper::convertFromUtc($booking->start_time, $booking->person_time_zone, 'Y-m-d H:i:s');
return date_i18n($format, strtotime($dateTime));
}
if (strpos($key, 'start_date_time_for_host') === 0) {
$format = preg_match('/format\.([a-zA-Z\-: ]+)/', $key, $matches) ? $matches[1] : 'Y-m-d H:i:s';
$dateTime = DateTimeHelper::convertFromUtc($booking->start_time, $booking->getHostTimezone(), 'Y-m-d H:i:s');
return date_i18n($format, strtotime($dateTime));
}
if ($key == 'cancel_reason') {
return $booking->getCancelReason(false, true);
}
if ($key == 'reject_reason') {
return $booking->getRejectReason(false, true);
}
if ($key == 'reschedule_reason') {
return $booking->getRescheduleReason(true);
}
if ($key == 'previous_meeting_time') {
return $booking->getPreviousMeetingTime($booking->getHostTimezone()) . ' (' . $booking->getHostTimezone() . ')';
}
if ($key == 'previous_meeting_time_guest_timezone') {
return $booking->getPreviousMeetingTime($booking->person_time_zone) . ' (' . $booking->person_time_zone . ')';
}
if ($key == 'previous_meeting_date_time_host_timezone') {
return $booking->getPreviousMeetingDateTimeText($booking->getHostTimezone()) . ' (' . $booking->getHostTimezone() . ')';
}
if ($key == 'previous_meeting_date_time_guest_timezone') {
return $booking->getPreviousMeetingDateTimeText($booking->person_time_zone) . ' (' . $booking->person_time_zone . ')';
}
if ($key == 'start_time_human_format') {
if (time() > strtotime($booking->start_time)) {
$suffix = __(' ago', 'fluent-booking');
} else {
$suffix = __(' from now', 'fluent-booking');
}
return human_time_diff(time(), strtotime($booking->start_time)) . ' ' . $suffix;
}
if ($key == 'cancelation_url') {
return $booking->getCancelUrl();
}
if ($key == 'reschedule_url') {
return $booking->getRescheduleUrl();
}
if ($key == 'admin_booking_url') {
return Helper::getAdminBookingUrl($booking->id) . '&period=upcoming';
}
if ($key == 'booking_confirm_url') {
return Helper::getAdminBookingUrl($booking->id) . '&period=pending&confirm_booking=true';
}
if ($key == 'booking_reject_url') {
return Helper::getAdminBookingUrl($booking->id) . '&period=pending&reject_booking=true';
}
if ($key == 'location_details_html') {
return $booking->getLocationDetailsHtml();
}
if ($key == 'location_details_text') {
return $booking->getLocationAsText();
}
if ($key == 'booking_hash') {
return $booking->hash;
}
$fillables = (new Booking())->getFillable();
$fillables[] = 'id';
$fillables[] = 'created_at';
$fillables[] = 'updated_at';
if (in_array($key, $fillables)) {
return $booking->{$key};
}
return '';
}
protected static function getBookingCustomData($key)
{
$booking = static::$store['booking'];
if (!$booking) {
return '';
}
if (self::$store['custom_booking_data'] === null) {
self::$store['custom_booking_data'] = $booking->getMeta('custom_fields_data', []);
}
if (self::$store['custom_booking_data']) {
if (preg_match('/format\.([a-zA-Z\-: ]+)/', $key, $matches)) {
$fieldKey = preg_split('/\.format\./', $key)[0];
$value = Arr::get(self::$store['custom_booking_data'], $fieldKey);
$customField = BookingFieldService::getBookingFieldByName($booking->calendar_event, $fieldKey);
$formattedDate = DateTimeHelper::getFormattedDate($value, Arr::get($customField, 'date_format'));
return $formattedDate ? date_i18n($matches[1], strtotime($formattedDate)) : '';
}
$customField = BookingFieldService::getBookingFieldByName($booking->calendar_event, $key);
if (Arr::get($customField, 'type') == 'file') {
return self::getUploadedFileUrl(Arr::get(self::$store['custom_booking_data'], $key));
}
if (Arr::get($customField, 'type') == 'hidden') {
static $resolving = [];
// Guest-supplied hidden values are parsed again, so a self-reference would recurse until the stack runs out.
if (isset($resolving[$key])) {
return Arr::get(self::$store['custom_booking_data'], $key);
}
$resolving[$key] = true;
try {
return self::parseShortCodes(Arr::get(self::$store['custom_booking_data'], $key));
} finally {
unset($resolving[$key]);
}
}
return Arr::get(self::$store['custom_booking_data'], $key);
}
return '';
}
protected static function getHostData($key)
{
$host = static::$store['host'];
if (is_null($host)) {
return '';
}
if ($key == 'timezone') {
$booking = static::$store['booking'];
return $booking ? $booking->getHostTimezone() : null;
}
return Arr::get($host, $key, '');
}
protected static function getTeamMembersData($key)
{
$teamMembers = static::$store['team_members'];
if (empty($teamMembers)) {
return '';
}
list($key, $value) = explode('.', $key);
return Arr::get($teamMembers, $key - 1 . '.' . $value, '');
}
protected static function getGuestData($key)
{
$guest = static::$store['booking'];
if (is_null($guest)) {
return '';
}
if ('full_name' == $key) {
return $guest['first_name'] . ' ' . $guest['last_name'];
}
if ('timezone' == $key) {
return $guest->person_time_zone;
}
if ('note' == $key) {
return $guest->getMessage();
}
if ($key == 'total_guest') {
return $guest->getTotalGuestCount();
}
if ($key == 'form_data_html') {
return __('will be available soon', 'fluent-booking');
}
return self::resolveScalarAttribute($guest, $key);
}
protected static function getBookingEventData($key)
{
$bookingEvent = static::$store['booking_event'];
if (is_null($bookingEvent)) {
return '';
}
$fillables = (new CalendarSlot())->getFillable();
if (in_array($key, $fillables)) {
return $bookingEvent->{$key};
}
return self::resolveScalarAttribute($bookingEvent, $key);
}
protected static function getCalendarData($key)
{
$calendar = static::$store['calendar'];
if (is_null($calendar)) {
return '';
}
$fillables = (new Calendar())->getFillable();
if (in_array($key, $fillables)) {
return $calendar->{$key};
}
return self::resolveScalarAttribute($calendar, $key);
}
/**
* Resolve a scalar attribute only; never a relation (dumps as JSON) or a
* dotted hop into a relation's columns.
*/
protected static function resolveScalarAttribute($model, $key)
{
if (strpos($key, '.') !== false) {
return '';
}
$value = isset($model[$key]) ? $model[$key] : '';
return is_scalar($value) ? $value : '';
}
protected static function getPaymentData($key)
{
$booking = static::$store['booking'];
if (is_null($booking)) {
return '';
}
if (!$booking->payment_status) {
return '';
}
if (is_null(static::$store['payment_order'])) {
static::$store['payment_order'] = $booking->payment_order;
}
if (!static::$store['payment_order']) {
return '';
}
$order = static::$store['payment_order'];
if ($key == 'payment_total' && $order) {
$isZeroDecimal = CurrenciesHelper::isZeroDecimal($order->currency);
if ($isZeroDecimal) {
return $order->total_amount;
} else {
return $order->total_amount / 100;
}
}
if ($key == 'receipt_html') {
return apply_filters('fluent_booking/payment_receipt_html', '', $booking->hash);
}
if ($key == 'payment_status') {
return $order ? $order->status : '';
}
if ($key == 'payment_currency') {
return $order ? $order->currency : '';
}
if ($key == 'payment_date') {
return $order ? $order->created_at : '';
}
$fillables = (new \FluentBookingPro\App\Models\Order())->getFillable();
if (in_array($key, $fillables)) {
return $order ? $order->{$key} : '';
}
return '';
}
protected static function getUserData($key)
{
$user = static::$store['user'];
if (is_null($user)) {
$user = wp_get_current_user();
}
return $user ? $user->{$key} : '';
}
protected static function getWPData($key)
{
if ('site_url' == $key) {
return site_url();
}
if ('admin_email' == $key) {
return get_option('admin_email');
}
if ('site_title' == $key) {
return get_option('blogname');
}
return $key;
}
protected static function getOtherData($key)
{
$meetingBookmarks = self::$store['meeting_bookmarks'];
if (!$meetingBookmarks) {
$booking = static::$store['booking'];
$meetingBookmarks = $booking ? $booking->getMeetingBookmarks() : null;
self::$store['meeting_bookmarks'] = $meetingBookmarks;
}
if (0 === strpos($key, 'date.')) {
$format = str_replace('date.', '', $key);
return gmdate($format, strtotime(current_time('mysql'))); // phpcs:ignore WordPress.DateTime.RestrictedFunctions.date_date
} elseif ('add_booking_to_calendar' === $key) {
return static::parseShortCodes(Helper::getAddToCalendarHtml());
} elseif ('add_to_g_calendar_url' === $key) {
return Arr::get($meetingBookmarks, 'google.url');
} elseif ('add_to_ol_calendar_url' === $key) {
return Arr::get($meetingBookmarks, 'outlook.url');
} elseif ('add_to_ms_calendar_url' === $key) {
return Arr::get($meetingBookmarks, 'msoffice.url');
} elseif ('add_to_ics_calendar_url' === $key) {
return Arr::get($meetingBookmarks, 'other.url');
}
return $key;
}
protected static function getUploadedFileUrl($fieldValue)
{
if (empty($fieldValue)) {
return '';
}
$files = array_map(function($file) {
return '' . esc_html(basename($file)) . '';
}, $fieldValue);
return '