user_id)) { $model->user_id = get_current_user_id(); } if (empty($model->hash)) { $model->hash = md5(wp_generate_uuid4() . time()); } }); } public function setSettingsAttribute($settings) { $originalSettings = $this->getOriginal('settings'); $originalSettings = \maybe_unserialize($originalSettings); foreach ($settings as $key => $value) { $originalSettings[$key] = $value; } $this->attributes['settings'] = \maybe_serialize($originalSettings); } public function getSettingsAttribute($settings) { return \maybe_unserialize($settings); } public function setLocationSettingsAttribute($locationSettings) { $this->attributes['location_settings'] = \maybe_serialize($locationSettings); } public function getLocationSettingsAttribute($locationSettings) { return \maybe_unserialize($locationSettings); } public function calendar() { return $this->belongsTo(Calendar::class, 'calendar_id'); } public function bookings() { return $this->hasMany(Booking::class, 'event_id'); } public function user() { return $this->belongsTo(User::class, 'user_id'); } public function event_metas() { return $this->hasMany(Meta::class, 'object_id', 'id') ->whereIn('object_type', ['calendar_event', 'integration']); } public function isGroup() { return $this->event_type == 'group'; } public function isSingleEvent() { return $this->event_type == 'single_event'; } public function isGroupEvent() { return $this->event_type == 'group_event'; } public function isRoundRobin() { return $this->event_type == 'round_robin'; } public function isCollective() { return $this->event_type == 'collective'; } public function isTeamEvent() { return $this->isRoundRobin() || $this->isCollective(); } public function isOneOffEvent() { return $this->isSingleEvent() || $this->isGroupEvent(); } public function isMultiHostEvent() { return $this->isTeamEvent() || $this->isOneOffEvent(); } public function isMultiHostsEvent() { return $this->isCollective() || $this->isOneOffEvent(); } public function isMultiGuestEvent() { return $this->isGroup() || $this->isGroupEvent(); } public function isProEvent() { return $this->isGroup() || $this->isTeamEvent() || $this->isOneOffEvent(); } public function allowMultiBooking() { return Arr::isTrue($this->settings, 'multiple_booking.enabled'); } public function multiBookingLimit() { return Arr::get($this->settings, 'multiple_booking.limit', 5); } public function getAuthorProfile($public = true, $userID = null) { $userID = $userID ?: $this->user_id; $user = get_user_by('id', $userID); if (!$user) { return false; } $name = trim($user->first_name . ' ' . $user->last_name); if (!$name) { $name = $user->display_name; } $data = [ 'ID' => $user->ID, 'name' => $name, 'avatar' => Helper::fluentBookingUserAvatar($user->ID, $user) ]; if (!$public) { $data['email'] = $user->user_email; } return $data; } public function getAuthorProfiles($public = true) { $teamMembers = []; $teamMemberIds = $this->getHostIds(); foreach ($teamMemberIds as $teamMemberId) { $calendar = Calendar::where('user_id', $teamMemberId)->where('type', 'simple')->first(); if ($calendar) { $teamMembers[] = $calendar->getAuthorProfile($public); } } return $teamMembers; } public function isLocationFieldRequired() { $locationSettings = Arr::get($this, 'location_settings'); if (count($locationSettings) > 1) { return true; } return false; } public function isPhoneRequired() { if (count($this->location_settings) == 1) { return Arr::get($this->location_settings, '0.type') == 'phone_guest'; } return false; } public function isAddressRequired() { if (count($this->location_settings) == 1) { return Arr::get($this->location_settings, '0.type') == 'in_person_guest'; } return false; } public function isGuestFieldRequired() { return true; } public function getEventDefaultData($calendar) { $weeklySchedule = Helper::getWeeklyScheduleSchema(); $availability = AvailabilityService::maybeCreateAvailability($calendar, $weeklySchedule); $defaultData = [ 'title' => '', 'calendar_id' => $calendar->id, 'user_id' => $calendar->user_id, 'status' => 'active', 'event_type' => 'single', 'description' => '', 'duration' => '30', 'color_schema' => '#0099ff', 'availability_type' => 'existing_schedule', 'availability_id' => (int)$availability->id, 'max_book_per_slot' => 1, 'is_display_spots' => false, 'location_settings' => [ [ 'type' => '', 'title' => '', 'description' => '', 'host_phone_number' => '' ] ], 'settings' => [ 'schedule_type' => 'weekly_schedules', 'weekly_schedules' => $weeklySchedule, 'date_overrides' => [], 'range_type' => 'range_days', 'range_days' => 60, 'range_date_between' => ['', ''], 'schedule_conditions' => [ 'value' => 4, 'unit' => 'hours' ] ] ]; return $defaultData; } public function getEventSchema($calendar) { $userCalendarId = $calendar->type == 'simple' ? $calendar->id : null; $settingsSchema = $this->getSlotSettingsSchema($userCalendarId); $schema = [ 'title' => '', 'status' => 'active', 'description' => '', 'duration' => '30', 'color_schema' => '#0099ff', 'calendar' => $calendar, 'settings' => $settingsSchema, 'max_book_per_slot' => 1, 'location_settings' => [ [ 'type' => '', 'title' => '', 'description' => '', 'host_phone_number' => '' ] ] ]; return $schema; } public function getSlotSettingsSchema($calendarId = null) { $calendarEvent = $calendarId ? CalendarSlot::where('calendar_id', $calendarId)->first() : null; return [ 'schedule_type' => 'weekly_schedules', 'weekly_schedules' => Helper::getWeeklyScheduleSchema(), 'date_overrides' => [], 'range_type' => 'range_days', 'range_days' => 60, 'range_date_between' => ['', ''], 'schedule_conditions' => [ 'value' => 4, 'unit' => 'hours' ], 'location_fields' => $this->getLocationFields($calendarEvent) ]; } public function getNotifications($isEdit = false) { $statuses = $this->getMeta('email_notifications'); if ($statuses) { $defaults = Helper::getDefaultEmailNotificationSettings(); foreach ($defaults as $key => $default) { if (isset($statuses[$key])) { if ($isEdit) { $statuses[$key]['title'] = $default['title']; } $emailBody = str_replace('fluent-booking-pro/core', 'fluent-booking', $statuses[$key]['email']['body']); $statuses[$key]['email']['body'] = $emailBody; } } if (!Arr::get($statuses, 'rescheduled_by_host')) { $statuses['rescheduled_by_host'] = $defaults['rescheduled_by_host']; } if (!Arr::get($statuses, 'rescheduled_by_attendee')) { $statuses['rescheduled_by_attendee'] = $defaults['rescheduled_by_attendee']; } if (!Arr::get($statuses, 'booking_request_host')) { $statuses['booking_request_host'] = $defaults['booking_request_host']; } if (!Arr::get($statuses, 'booking_request_attendee')) { $statuses['booking_request_attendee'] = $defaults['booking_request_attendee']; } if (!Arr::get($statuses, 'declined_by_host')) { $statuses['declined_by_host'] = $defaults['declined_by_host']; } return $statuses; } return Helper::getDefaultEmailNotificationSettings(); } public function setNotifications($notifications) { $this->updateMeta('email_notifications', $notifications); } public function getBookingFields() { return BookingFieldService::getBookingFields($this); } public function setBookingFields($bookingFields) { return $this->updateMeta('booking_fields', $bookingFields); } public function getScheduleTimezone($hostId = null) { if ($hostId && !$this->isTeamCommonSchedule()) { $schedule = AvailabilityService::getDefaultSchedule($hostId); return Arr::get($schedule, 'value.timezone', 'UTC'); } if ($this->availability_type == 'existing_schedule') { $schedule = Availability::findOrFail($this->availability_id); return Arr::get($schedule, 'value.timezone', 'UTC'); } return $this->calendar->author_timezone; } public function isMultiDurationEnabled() { return Arr::isTrue($this->settings, 'multi_duration.enabled'); } public function getDuration($duration = null) { if ($this->isMultiDurationEnabled()) { if (in_array($duration, Arr::get($this->settings, 'multi_duration.available_durations', []))) { return $duration; } else { return Arr::get($this->settings, 'multi_duration.default_duration', ''); } } return $this->duration; } public function getDefaultDuration() { if ($this->isMultiDurationEnabled()) { return Arr::get($this->settings, 'multi_duration.default_duration', ''); } return $this->duration; } public function getAvailableDurations() { if ($this->isMultiDurationEnabled()) { $durationLookup = Helper::getDurationLookup(true); $availableDurations = Arr::get($this->settings, 'multi_duration.available_durations', []); return array_map(function ($duration) use ($durationLookup) { return $durationLookup[$duration]; }, $availableDurations); } $durationLookup = Helper::getDurationLookup(); $duration = $durationLookup[$this->duration] ?? Helper::formatDuration($this->duration); return [$duration]; } public function getDescription() { if ($this->description) { return $this->description; } if ($this->isMultiDurationEnabled()) { return __('Choose your duration and book a meeting with me', 'fluent-booking'); } // translators: %d is the duration of the meeting in minutes return sprintf(__('Book a meeting with me for %d minutes', 'fluent-booking'), $this->duration); } public function getSlotInterval($duration = null) { $duration = $duration ?: $this->duration; $interval = Arr::get($this->settings, 'slot_interval', ''); $slotInterval = empty($interval) ? $duration : intval($interval); return $slotInterval; } public function isReserveTime() { return Arr::isTrue($this->settings, 'reserve_time', false); } public function getAvailableTimes() { return Arr::get($this->settings, 'available_times', []); } public function getTotalBufferTime() { $bufferTimeBefore = Arr::get($this->settings, 'buffer_time_before', 0); $bufferTimeAfter = Arr::get($this->settings, 'buffer_time_after', 0); return $bufferTimeBefore + $bufferTimeAfter; } public function getMaxBookableDateTime($startDate, $timeZone = 'UTC', $format = 'Y-m-d 23:59:59') { $rangeType = Arr::get($this->settings, 'range_type', 'range_days'); $lastDay = gmdate('Y-m-t 23:59:59', strtotime($startDate)); // phpcs:ignore WordPress.DateTime.RestrictedFunctions.date_date if ($timeZone != 'UTC') { $lastDay = DateTimeHelper::convertToTimeZone($lastDay, $timeZone, 'UTC', $format); } if ($rangeType == 'range_indefinite') { return $lastDay; } $maxLookupDate = $this->getMaxLookUpDate(); $maxDate = DateTimeHelper::convertToTimeZone($maxLookupDate, $this->calendar->author_timezone, 'UTC'); if (strtotime($maxDate) > strtotime($lastDay)) { return $lastDay; } return $maxDate; } public function getMinBookableDateTime($startDate = null, $timeZone = null) { $startDate = $startDate ?: gmdate('Y-m-d H:i:s'); // phpcs:ignore WordPress.DateTime.RestrictedFunctions.date_date $rangeType = Arr::get($this->settings, 'range_type', 'range_days'); if ($rangeType == 'range_date_between') { $range = Arr::get($this->settings, 'range_date_between', []); if (is_array($range) && count(array_filter($range)) == 2) { if (strtotime($range[0]) >= strtotime($startDate)) { $startDate = gmdate('Y-m-d H:i:s', strtotime($range[0])); // phpcs:ignore WordPress.DateTime.RestrictedFunctions.date_date } } } $totalCutStamp = DateTimeHelper::getTimestamp() + $this->getCutoutSeconds(); if (strtotime($startDate) < $totalCutStamp) { $startDate = gmdate('Y-m-d H:i:s', $totalCutStamp); // phpcs:ignore WordPress.DateTime.RestrictedFunctions.date_date } return $startDate; } public function getMaxLookUpDate() { $rangeType = Arr::get($this->settings, 'range_type', 'range_days'); if ($rangeType == 'range_indefinite') { return false; } if ($rangeType == 'range_date_between') { $range = Arr::get($this->settings, 'range_date_between', []); if (is_array($range) && count(array_filter($range)) == 2) { return gmdate('Y-m-d 23:59:59', strtotime($range[1])); // phpcs:ignore WordPress.DateTime.RestrictedFunctions.date_date } } $rangeDays = Arr::get($this->settings, 'range_days', 60) ?: 60; return gmdate('Y-m-d 23:59:59', time() + $rangeDays * DAY_IN_SECONDS); // phpcs:ignore WordPress.DateTime.RestrictedFunctions.date_date } public function getMinLookUpDate($timeZone = 'UTC') { $rangeType = Arr::get($this->settings, 'range_type', 'range_days'); $minDate = gmdate('Y-m-d H:i:s'); // phpcs:ignore WordPress.DateTime.RestrictedFunctions.date_date if ($rangeType == 'range_date_between') { $range = Arr::get($this->settings, 'range_date_between', []); if (is_array($range) && count(array_filter($range)) == 2) { $minDate = gmdate('Y-m-d H:i:s', strtotime($range[0])); // phpcs:ignore WordPress.DateTime.RestrictedFunctions.date_date } } if ($timeZone != 'UTC') { $minDate = DateTimeHelper::convertToTimeZone($minDate, $timeZone, 'UTC'); } return $minDate; } public function getCutoutSeconds() { $conditions = Arr::get($this->settings, 'schedule_conditions', []); if (!$conditions || empty($conditions['unit'])) { return 0; } return strtotime('+' . $conditions['value'] . ' ' . $conditions['unit'], 0) - strtotime('+0 seconds', 0); } public function getHostIds($hostId = null) { if ($hostId) { return [$hostId]; } if ($this->isMultiHostEvent()) { return Arr::get($this->settings, 'team_members', []); } return [$this->user_id]; } public function getMaxBookingPerSlot() { return $this->max_book_per_slot; } public function getPublicUrl() { $calendar = $this->calendar; if (!$calendar) { return false; } $baseUr = $calendar->getLandingPageUrl(); if (!$baseUr) { return ''; } if (defined('FLUENT_BOOKING_LANDING_SLUG')) { return $baseUr . '/' . $this->slug; } return $baseUr . '&event=' . $this->slug; } public function getMeta($key, $default = null) { $meta = Meta::where('object_type', 'calendar_event') ->where('object_id', $this->id) ->where('key', $key) ->first(); if (!$meta) { return $default; } return $meta->value; } public function updateMeta($key, $value) { $exist = Meta::where('object_type', 'calendar_event') ->where('object_id', $this->id) ->where('key', $key) ->first(); if ($exist) { $exist->value = $value; $exist->save(); } else { $exist = Meta::create([ 'object_type' => 'calendar_event', 'object_id' => $this->id, 'key' => $key, 'value' => $value ]); } return $exist; } public function getLocationFields($calendarEvent = null) { return apply_filters('fluent_booking/get_location_fields', [ 'conferencing' => [ 'label' => __('Conferencing', 'fluent-booking'), 'options' => [ 'google_meet' => [ 'title' => __('Google Meet (Pro)', 'fluent-booking'), 'disabled' => true, 'location_type' => 'conferencing' ], 'ms_teams' => [ 'title' => __('MS Teams (Pro)', 'fluent-booking'), 'disabled' => true, 'location_type' => 'conferencing' ], 'zoom_meeting' => [ 'title' => __('Zoom Video (Pro)', 'fluent-booking'), 'disabled' => true, 'location_type' => 'conferencing' ], ], ], 'in_person' => [ 'label' => __('In Person', 'fluent-booking'), 'options' => [ 'in_person_guest' => [ 'title' => __('In Person (Attendee Address)', 'fluent-booking'), ], 'in_person_organizer' => [ 'title' => __('In Person (Organizer Address)', 'fluent-booking'), ], ], ], 'phone' => [ 'label' => __('Phone', 'fluent-booking'), 'options' => [ 'phone_guest' => [ 'title' => __('Attendee Phone Number', 'fluent-booking'), ], 'phone_organizer' => [ 'title' => __('Organizer Phone Number', 'fluent-booking'), ], ], ], 'online' => [ 'label' => __('Online', 'fluent-booking'), 'options' => [ 'online_meeting' => [ 'title' => __('Online Meeting', 'fluent-booking'), ], ], ], 'other' => [ 'label' => __('Other', 'fluent-booking'), 'options' => [ 'custom' => [ 'title' => __('Custom', 'fluent-booking'), ], ], ], ], $calendarEvent ?: $this); } public function isDisplaySpots() { return $this->is_display_spots == true; } public function isAdditionalGuestEnabled() { $guestField = BookingFieldService::getBookingFieldByName($this, 'guests'); return Arr::isTrue($guestField, 'enabled', false); } public function isConfirmationEnabled() { return Arr::isTrue($this->settings, 'requires_confirmation.enabled'); } public function isConfirmationRequired($bookingStartTime, $bookingCreatedTime = null) { if (!$this->isConfirmationEnabled() || !is_string($bookingStartTime)) { return false; } $type = Arr::get($this->settings, 'requires_confirmation.type', 'always'); if ($type == 'always') { return true; } $bookingStartTime = strtotime($bookingStartTime); $bookingCreatedTime = $bookingCreatedTime ? strtotime($bookingCreatedTime) : time(); $conditionUnit = Arr::get($this->settings, 'requires_confirmation.condition.unit', 'minutes'); $conditionValue = Arr::get($this->settings, 'requires_confirmation.condition.value', 0); $conditionTime = $conditionValue * 60; if ($conditionUnit == 'hours') { $conditionTime = $conditionTime * 60; } return $bookingStartTime - $bookingCreatedTime < $conditionTime; } public function getCanNotCancelSettings() { if (!isset($this->settings['can_not_cancel'])) { $enabled = Arr::get($this->settings, 'can_cancel') == 'no' ? true : false; return [ 'enabled' => $enabled, 'type' => 'always', ]; } return Arr::get($this->settings, 'can_not_cancel', []); } public function getCanNotRescheduleSettings() { if (!isset($this->settings['can_not_reschedule'])) { $enabled = Arr::get($this->settings, 'can_reschedule') == 'no' ? true : false; return [ 'enabled' => $enabled, 'type' => 'always', ]; } return Arr::get($this->settings, 'can_not_reschedule', []); } public function defaultLocationHtml() { if (empty($this->location_settings)) { return ''; } $default = Arr::get($this, 'location_settings'); if (!$default) { return ''; } return LocationService::getLocationIconHeadingHtml($default, $this); } public function defaultPaymentIcon($currency, $amount) { $svg = ''; $html = '' . $svg . $currency . $amount . ''; return $html; } public function isPaymentEnabled($duration = null) { if ($this->isMultiDurationEnabled()) { $paymentSettings = $this->getPaymentSettings(); if (Arr::get($paymentSettings, 'multi_payment_enabled') == 'yes') { $duration = $duration ?? $this->getDefaultDuration(); if (!Arr::get($paymentSettings, 'multi_payment_items.' . $duration . '.value')) { return false; } } } return $this->type == 'paid' && Helper::isPaymentEnabled(); } public function isWooEnabled() { return $this->type == 'woo' && defined('WC_PLUGIN_FILE'); } public function getPaymentItems($duration = null) { $paymentSettings = $this->getPaymentSettings(); $isMultiEnabled = Arr::get($paymentSettings, 'multi_payment_enabled') == 'yes'; if ($this->isMultiDurationEnabled() && $isMultiEnabled) { $duration = $duration ?? $this->getDefaultDuration(); return [Arr::get($paymentSettings, 'multi_payment_items.' . $duration)]; } return Arr::get($paymentSettings, 'items', []); } public function getPricingTotal() { if (!$this->isPaymentEnabled()) { return 0; } $total = 0; $items = $this->getPaymentItems(); foreach ($items as $item) { $total += (int)$item['value']; } return $total; } public function getWooProductPrice() { $paymentSettings = $this->getPaymentSettings(); $productId = $paymentSettings['woo_product_id']; if (Arr::get($paymentSettings, 'multi_payment_enabled') == 'yes') { $duration = $this->getDefaultDuration(); $productId = Arr::get($paymentSettings, 'multi_payment_woo_ids.' . $duration); } $price = 0; $product = wc_get_product($productId); if ($product) { $price = $product->get_price(); } return $price; } public function getWooProductPriceByDuration($productIds = []) { $productPrices = []; foreach ($productIds as $duration => $productId) { $product = wc_get_product($productId); if ($product) { $productPrices[$duration] = [ 'value' => $product->get_price() ]; } } return $productPrices; } public function getPaymentHtml() { $paymentHtml = ''; $driver = Arr::get($this->getPaymentSettings(), 'driver'); if ($driver == 'native' && $this->isPaymentEnabled()) { $currency = CurrenciesHelper::getGlobalCurrencySign(); $totalPayment = $this->getPricingTotal(); $paymentHtml = $this->defaultPaymentIcon($currency, $totalPayment); } if ($driver == 'woo' && $this->isWooEnabled()) { $currency = get_woocommerce_currency_symbol(); $totalPayment = $this->getWooProductPrice(); $paymentHtml = $this->defaultPaymentIcon($currency, $totalPayment); } return $paymentHtml; } public function isTeamDefaultSchedule() { if ($this->isTeamEvent()) { if (!Arr::isTrue($this->settings, 'common_schedule', false)) { return true; } } return false; } public function isTeamCommonSchedule() { if ($this->isTeamEvent()) { if (Arr::isTrue($this->settings, 'common_schedule', false)) { return true; } } return false; } public function isRoundRobinDefaultSchedule() { return $this->isRoundRobin() && $this->isTeamDefaultSchedule(); } public function isRoundRobinCommonSchedule() { return $this->isRoundRobin() && $this->isTeamCommonSchedule(); } private function getProcessedWeeklySlots($schedule) { $scheduleData = Arr::get($schedule, 'value.weekly_schedules', []); $scheduleTimezone = Arr::get($schedule, 'value.timezone', 'UTC'); $schedule = SanitizeService::weeklySchedules($scheduleData, 'UTC', $scheduleTimezone); return AvailabilityService::getUtcWeeklySchedules($schedule, $scheduleTimezone); } private function getProcessedDateOverrides($schedule) { $scheduleData = Arr::get($schedule, 'value.date_overrides', []); $scheduleTimezone = Arr::get($schedule, 'value.timezone', 'UTC'); $schedule = SanitizeService::slotDateOverrides($scheduleData, 'UTC', $scheduleTimezone); $overrideSlots = AvailabilityService::getUtcDateOverrides($schedule, $scheduleTimezone); $overrideDays = AvailabilityService::getDateOverrideDays($schedule, $scheduleTimezone); return [$overrideSlots, $overrideDays]; } public function getWeeklySlots($hostId = null) { if ($hostId && !$this->isTeamCommonSchedule()) { $schedule = AvailabilityService::getDefaultSchedule($hostId); return $this->getProcessedWeeklySlots($schedule); } if ($this->availability_type === 'existing_schedule') { $schedule = Availability::findOrFail($this->availability_id); return $this->getProcessedWeeklySlots($schedule); } $scheduleData = Arr::get($this->settings, 'weekly_schedules', []); $schedule = SanitizeService::weeklySchedules($scheduleData, 'UTC', $this->calendar->author_timezone); return AvailabilityService::getUtcWeeklySchedules($schedule, $this->calendar->author_timezone); } public function getDateOverrides($hostId = null) { if ($hostId && !$this->isTeamCommonSchedule()) { $schedule = AvailabilityService::getDefaultSchedule($hostId); return $this->getProcessedDateOverrides($schedule); } if ($this->availability_type === 'existing_schedule') { $schedule = Availability::findOrFail($this->availability_id); return $this->getProcessedDateOverrides($schedule); } $scheduleData = Arr::get($this->settings, 'date_overrides', []); $schedule = SanitizeService::slotDateOverrides($scheduleData, 'UTC', $this->calendar->author_timezone); $overrideSlots = AvailabilityService::getUtcDateOverrides($schedule, $this->calendar->author_timezone); $overrideDays = AvailabilityService::getDateOverrideDays($schedule, $this->calendar->author_timezone); return [$overrideSlots, $overrideDays]; } public function getHostIdsSortedByBookings($startDate, $hostId = null) { $hostIds = $this->getHostIds($hostId); if (count($hostIds) <= 1) { return $hostIds; } $hostBookings = []; foreach ($hostIds as $hostId) { $dayStart = gmdate('Y-m-d 00:00:00', strtotime($startDate)); // phpcs:ignore WordPress.DateTime.RestrictedFunctions.date_date $dayEnd = gmdate('Y-m-d 23:59:59', strtotime($startDate)); // phpcs:ignore WordPress.DateTime.RestrictedFunctions.date_date $hostBookings[$hostId] = Booking::getHostTotalBooking($this->id, [$hostId], [$dayStart, $dayEnd]); } usort($hostIds, function ($a, $b) use ($hostBookings) { return $hostBookings[$a] - $hostBookings[$b]; }); return $hostIds; } public function getPaymentSettings() { $settings = $this->getMeta('payment_settings', []); $duration = $this->getDefaultDuration(); $defaults = [ 'enabled' => 'no', 'multi_payment_enabled' => 'no', 'stripe_enabled' => 'no', 'paypal_enabled' => 'no', 'driver' => 'native', 'items' => [ [ 'title' => __('Booking Fee', 'fluent-booking'), 'value' => 100 ] ], 'woo_product_id' => '', 'multi_payment_items' => [ $duration => [ 'title' => __('Booking Fee', 'fluent-booking'), 'value' => 0 ] ], 'multi_payment_woo_ids' => [ $duration => '' ] ]; if (!$settings) { $settings = $defaults; } return wp_parse_args($settings, $defaults); } public function getCalendarEventsMeta() { $eventsMeta = Meta::where('object_id', $this->id) ->where('object_type', 'calendar_event') ->get(); return $eventsMeta; } public function getIntegrationsMeta() { $integrationsMeta = Meta::where('object_id', $this->id) ->where('object_type', 'integration') ->get(); return $integrationsMeta; } /** * Get the attributes that have been changed since last sync. * * @return array */ public function getDirty() { $dirty = []; foreach ($this->attributes as $key => $value) { if (!in_array($key, $this->fillable)) { continue; } if (!array_key_exists($key, $this->original)) { $dirty[$key] = $value; } elseif ($value !== $this->original[$key] && !$this->originalIsNumericallyEquivalent($key)) { $dirty[$key] = $value; } } return $dirty; } }