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
fluent-booking / app / Services / NotificationGate.php

NotificationGate.php in Fluent Booking – The Ultimate Appointments Scheduling, Events Booking, Events Calendar Solution trunk, at app/Services/NotificationGate.php

84 lines 2.8 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 /**
6 * A request-scoped switch that stops booking notifications from going out.
7 *
8 * Some programmatic callers legitimately need to change a booking without
9 * emailing the attendee — an operator backfilling a booking that was already
10 * agreed on the phone, a data migration, an AI agent acting on the host's
11 * behalf. There was previously no way to express that: notifications are wired
12 * to the booking lifecycle hooks, and suppressing them meant unhooking whole
13 * actions, which also silenced calendar sync, CRM triggers and webhooks.
14 *
15 * This gate is deliberately narrow. It suppresses *notifications only*.
16 * Everything else a booking triggers still runs.
17 *
18 * The gate is request-scoped, so it covers notifications sent during the call
19 * only. Reminders belong to the booking, not to the operation that moved it:
20 * a silent create or reschedule still leaves the event's reminder schedule
21 * intact, and the attendee gets their reminder as normal.
22 *
23 * Usage:
24 *
25 * $booking = NotificationGate::silently(function () use ($data) {
26 * return BookingService::createBooking($data);
27 * });
28 *
29 * Add-ons that send their own notifications (SMS, push) should check
30 * NotificationGate::isSuppressed() at the top of their handlers, or hook the
31 * `fluent_booking/suppress_notifications` filter.
32 *
33 * @since 2.2.6
34 */
35 class NotificationGate
36 {
37 /**
38 * @var bool
39 */
40 private static $suppressed = false;
41
42 /**
43 * Run $callback with notifications turned off, then restore the previous
44 * state — including when $callback throws, so one failed call cannot leave
45 * the rest of the request silent.
46 *
47 * @param callable $callback
48 *
49 * @return mixed Whatever $callback returns.
50 */
51 public static function silently(callable $callback)
52 {
53 $previous = self::$suppressed;
54 self::$suppressed = true;
55
56 try {
57 return $callback();
58 } finally {
59 self::$suppressed = $previous;
60 }
61 }
62
63 /**
64 * @param string $context A hint about which notification is being gated,
65 * e.g. 'booking_scheduled' or 'booking_cancelled'.
66 * @param mixed $booking The booking in play, when there is one.
67 *
68 * @return bool
69 */
70 public static function isSuppressed($context = '', $booking = null)
71 {
72 /**
73 * Whether booking notifications should be skipped for this call.
74 *
75 * @since 2.2.6
76 *
77 * @param bool $suppressed Current state of the request-scoped gate.
78 * @param string $context Which notification is being gated.
79 * @param mixed $booking The booking in play, or null.
80 */
81 return (bool) apply_filters('fluent_booking/suppress_notifications', self::$suppressed, $context, $booking);
82 }
83 }
84