| @@ -3,8 +3,9 @@ | ||
| 3 | 3 | namespace FluentBooking\App\Hooks\Handlers; |
| 4 | 4 | |
| 5 | 5 | use FluentBooking\App\Models\Booking; |
| 6 | 6 | use FluentBooking\App\Services\EmailNotificationService; |
| 7 | +use FluentBooking\App\Services\NotificationGate; | |
| 7 | 8 | use FluentBooking\Framework\Support\Arr; |
| 8 | 9 | |
| 9 | 10 | class NotificationHandler |
| 10 | 11 | { |
| @@ -35,8 +36,13 @@ | ||
| 35 | 36 | } |
| 36 | 37 | |
| 37 | 38 | private function pushRemindersToQueue($booking, $reminderTimes, $emailTo) |
| 38 | 39 | { |
| 40 | + // A booking can be scheduled again (e.g. no_show back to scheduled); replace, don't stack. | |
| 41 | + \as_unschedule_all_actions('fluent_booking/booking_schedule_reminder', [$booking->id, $emailTo], 'fluent-booking'); | |
| 42 | + | |
| 43 | + $this->clearGroupRemindersForHost($booking, $emailTo); | |
| 44 | + | |
| 39 | 45 | foreach ($reminderTimes as $time) { |
| 40 | 46 | $reminderTimestamp = $this->getReminderTime($time); |
| 41 | 47 | |
| 42 | 48 | $happeningTimestamp = strtotime($booking->start_time); |
| @@ -51,19 +57,25 @@ | ||
| 51 | 57 | } |
| 52 | 58 | } |
| 53 | 59 | } |
| 54 | 60 | |
| 61 | + private function clearGroupRemindersForHost($booking, $emailTo) | |
| 62 | + { | |
| 63 | + if (!$booking->isMultiGuestBooking() || $emailTo != 'host') { | |
| 64 | + return; | |
| 65 | + } | |
| 66 | + | |
| 67 | + $otherBookingIds = Booking::where('group_id', $booking->group_id)->where('id', '!=', $booking->id)->pluck('id')->toArray(); | |
| 68 | + | |
| 69 | + foreach ($otherBookingIds as $otherBookingId) { | |
| 70 | + \as_unschedule_all_actions('fluent_booking/booking_schedule_reminder', [$otherBookingId, 'host'], 'fluent-booking'); | |
| 71 | + } | |
| 72 | + } | |
| 73 | + | |
| 55 | 74 | public function pushBookingScheduledToQueue($booking, $bookingEvent) |
| 56 | 75 | { |
| 57 | 76 | $notifications = $bookingEvent->getNotifications(); |
| 58 | 77 | |
| 59 | - if (Arr::isTrue($notifications, 'booking_conf_attendee.enabled') || (Arr::isTrue($notifications, 'booking_conf_host.enabled'))) { | |
| 60 | - as_enqueue_async_action('fluent_booking/after_booking_scheduled_async', [ | |
| 61 | - $booking->id, | |
| 62 | - $bookingEvent->id | |
| 63 | - ], 'fluent-booking'); | |
| 64 | - } | |
| 65 | - | |
| 66 | 78 | if (Arr::isTrue($notifications, 'reminder_to_attendee.enabled')) { |
| 67 | 79 | $reminderTimes = Arr::get($notifications, 'reminder_to_attendee.email.times', []); |
| 68 | 80 | $this->pushRemindersToQueue($booking, $reminderTimes, 'guest'); |
| 69 | 81 | } |
| @@ -71,12 +83,31 @@ | ||
| 71 | 83 | if (Arr::isTrue($notifications, 'reminder_to_host.enabled')) { |
| 72 | 84 | $reminderTimes = Arr::get($notifications, 'reminder_to_host.email.times', []); |
| 73 | 85 | $this->pushRemindersToQueue($booking, $reminderTimes, 'host'); |
| 74 | 86 | } |
| 87 | + | |
| 88 | + if (!is_null($booking->parent_id) && $booking->isRecurringBooking()) { | |
| 89 | + return; | |
| 90 | + } | |
| 91 | + | |
| 92 | + if (NotificationGate::isSuppressed('booking_scheduled', $booking)) { | |
| 93 | + return; | |
| 94 | + } | |
| 95 | + | |
| 96 | + if (Arr::isTrue($notifications, 'booking_conf_attendee.enabled') || (Arr::isTrue($notifications, 'booking_conf_host.enabled'))) { | |
| 97 | + as_enqueue_async_action('fluent_booking/after_booking_scheduled_async', [ | |
| 98 | + $booking->id, | |
| 99 | + $bookingEvent->id | |
| 100 | + ], 'fluent-booking'); | |
| 101 | + } | |
| 75 | 102 | } |
| 76 | 103 | |
| 77 | 104 | public function pushBookingPendingToQueue($booking, $bookingEvent) |
| 78 | 105 | { |
| 106 | + if (NotificationGate::isSuppressed('booking_pending', $booking)) { | |
| 107 | + return; | |
| 108 | + } | |
| 109 | + | |
| 79 | 110 | if (!$bookingEvent->isConfirmationEnabled() || $bookingEvent->isMultiGuestEvent()) { |
| 80 | 111 | return; |
| 81 | 112 | } |
| 82 | 113 | |
| @@ -83,8 +114,12 @@ | ||
| 83 | 114 | if ($booking->payment_method && $booking->payment_status != 'paid') { |
| 84 | 115 | return; |
| 85 | 116 | } |
| 86 | 117 | |
| 118 | + if (!is_null($booking->parent_id) && $booking->isRecurringBooking()) { | |
| 119 | + return; | |
| 120 | + } | |
| 121 | + | |
| 87 | 122 | $notifications = $bookingEvent->getNotifications(); |
| 88 | 123 | |
| 89 | 124 | if (Arr::isTrue($notifications, 'booking_request_host.enabled') || (Arr::isTrue($notifications, 'booking_request_attendee.enabled'))) { |
| 90 | 125 | as_enqueue_async_action('fluent_booking/after_booking_pending_async', [ |
| @@ -95,8 +130,12 @@ | ||
| 95 | 130 | } |
| 96 | 131 | |
| 97 | 132 | public function emailToUpdatedEmail($booking, $calendarEvent) |
| 98 | 133 | { |
| 134 | + if (NotificationGate::isSuppressed('booking_email_changed', $booking)) { | |
| 135 | + return; | |
| 136 | + } | |
| 137 | + | |
| 99 | 138 | $notifications = $calendarEvent->getNotifications(); |
| 100 | 139 | |
| 101 | 140 | if (Arr::isTrue($notifications, 'booking_conf_attendee.enabled') || (Arr::isTrue($notifications, 'booking_conf_host.enabled'))) { |
| 102 | 141 | as_enqueue_async_action('fluent_booking/after_booking_scheduled_async', [ |
| @@ -194,19 +233,20 @@ | ||
| 194 | 233 | } |
| 195 | 234 | |
| 196 | 235 | public function getAdditionalRecipients($additionalRecipients) |
| 197 | 236 | { |
| 198 | - if ($additionalRecipients) { | |
| 199 | - $recipients = explode(',', $additionalRecipients); | |
| 200 | - $recipients = array_map('trim', $recipients); | |
| 201 | - return array_unique($recipients); | |
| 237 | + if (!$additionalRecipients) { | |
| 238 | + return []; | |
| 202 | 239 | } |
| 203 | - return []; | |
| 240 | + | |
| 241 | + $recipients = explode(',', $additionalRecipients); | |
| 242 | + $recipients = array_map('trim', $recipients); | |
| 243 | + return array_unique($recipients); | |
| 204 | 244 | } |
| 205 | 245 | |
| 206 | 246 | public function emailOnBookingCancelled(Booking $booking, $calendarEvent) |
| 207 | 247 | { |
| 208 | - if (!$calendarEvent) { | |
| 248 | + if (!$calendarEvent || NotificationGate::isSuppressed('booking_cancelled', $booking)) { | |
| 209 | 249 | return; |
| 210 | 250 | } |
| 211 | 251 | |
| 212 | 252 | $notifications = $calendarEvent->getNotifications(); |
| @@ -246,10 +286,10 @@ | ||
| 246 | 286 | return; |
| 247 | 287 | } |
| 248 | 288 | |
| 249 | 289 | // Remove all reminders |
| 250 | - as_unschedule_all_actions('fluent_booking/booking_schedule_reminder', [$oldBooking->id, 'host'], 'fluent-booking'); | |
| 251 | - as_unschedule_all_actions('fluent_booking/booking_schedule_reminder', [$oldBooking->id, 'guest'], 'fluent-booking'); | |
| 290 | + \as_unschedule_all_actions('fluent_booking/booking_schedule_reminder', [$oldBooking->id, 'host'], 'fluent-booking'); | |
| 291 | + \as_unschedule_all_actions('fluent_booking/booking_schedule_reminder', [$oldBooking->id, 'guest'], 'fluent-booking'); | |
| 252 | 292 | |
| 253 | 293 | if (Arr::isTrue($notifications, 'reminder_to_attendee.enabled')) { |
| 254 | 294 | $reminderTimes = Arr::get($notifications, 'reminder_to_attendee.email.times', []); |
| 255 | 295 | $this->pushRemindersToQueue($booking, $reminderTimes, 'guest'); |
| @@ -259,8 +299,12 @@ | ||
| 259 | 299 | $reminderTimes = Arr::get($notifications, 'reminder_to_host.email.times', []); |
| 260 | 300 | $this->pushRemindersToQueue($booking, $reminderTimes, 'host'); |
| 261 | 301 | } |
| 262 | 302 | |
| 303 | + if (NotificationGate::isSuppressed('booking_rescheduled', $booking)) { | |
| 304 | + return; | |
| 305 | + } | |
| 306 | + | |
| 263 | 307 | $rescheduledBy = $booking->getMeta('rescheduled_by_type', 'host'); |
| 264 | 308 | |
| 265 | 309 | if ($rescheduledBy == 'host') { |
| 266 | 310 | if (Arr::isTrue($notifications, 'rescheduled_by_host.enabled')) { |
| @@ -282,9 +326,9 @@ | ||
| 282 | 326 | } |
| 283 | 327 | |
| 284 | 328 | public function emailOnBookingRejected(Booking $booking, $calendarEvent) |
| 285 | 329 | { |
| 286 | - if (!$calendarEvent) { | |
| 330 | + if (!$calendarEvent || NotificationGate::isSuppressed('booking_rejected', $booking)) { | |
| 287 | 331 | return; |
| 288 | 332 | } |
| 289 | 333 | |
| 290 | 334 | $notifications = $calendarEvent->getNotifications(); |