PluginProbe
Fluent Booking – The Ultimate Appointments Scheduling, Events Booking, Events Calendar Solution / 2.5.0
Fluent Booking – The Ultimate Appointments Scheduling, Events Booking, Events Calendar Solution v2.5.0
2.5.0 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 All 34 releases
← All changes | app/Services/RescheduleService.php +8 -23 2.4.0 → 2.5.0 View file →
@@ -5,21 +5,12 @@
5 5 use FluentBooking\App\Models\Booking;
6 6 use FluentBooking\App\Models\CalendarSlot;
7 7
8 8 /**
9 - * Moves an existing booking to a new time.
9 + * Moves an existing booking to a new time. Shared by the public form and
10 + * programmatic callers such as MCP, so all fire the same hooks. Failures come
11 + * back as WP_Error. A reschedule changes the time and leaves `status` alone.
10 12 *
11 - * This logic used to live inline in FrontEndHandler::handleRescheduling(), where
12 - * it was reachable only through the public booking form and signalled every
13 - * failure with wp_send_json() — which made it impossible to call from anywhere
14 - * else without terminating the request. It is extracted here so the public form
15 - * and programmatic callers (the MCP server among them) run the exact same steps
16 - * and emit the exact same hooks. Failures come back as WP_Error; the caller
17 - * decides how to render them.
18 - *
19 - * Behaviour is intentionally identical to the original inline version: a
20 - * reschedule changes the time and leaves `status` alone.
21 - *
22 13 * @since 2.2.6
23 14 */
24 15 class RescheduleService
25 16 {
@@ -40,12 +31,9 @@
40 31 * @return Booking|\WP_Error The updated booking, or the reason it was refused.
41 32 */
42 33 public static function reschedule(Booking $booking, CalendarSlot $calendarEvent, $startTime, $timezone, $args = [])
43 34 {
44 - // The booking must be rescheduled against its own event. Reject mixed-object
45 - // requests where the posted event_id differs from the booking's event so the
46 - // availability validation cannot be performed under a different event than the
47 - // one actually being modified.
35 + // Availability must be validated against the booking's own event.
48 36 if ((int) $booking->event_id !== (int) $calendarEvent->id) {
49 37 return new \WP_Error('invalid_reschedule_request', __('Invalid rescheduling request', 'fluent-booking'), ['status' => 422]);
50 38 }
51 39
@@ -64,20 +52,17 @@
64 52 $previousBooking = clone $booking;
65 53
66 54 $reason = isset($args['reason']) ? sanitize_textarea_field($args['reason']) : '';
67 55
68 - // The pivot is synced before the row is saved, so a failure between them
69 - // left hosts() naming the new host while the row said the old one.
56 + // The host pivot syncs before the row saves, so keep both in one transaction.
70 57 try {
71 58 Helper::dbTransaction(function () use ($booking, $rescheduleBy, $startTime, $timezone, $endDateTime, $previousBooking, $reason, $args) {
72 - // Below the guards: both return, so writing above them stamped a
73 - // reschedule that never happened, and NotificationHandler reads
74 - // this to pick the host- or attendee-worded email.
59 + // Written after the guards so a refused reschedule leaves no trace.
60 + // NotificationHandler reads it to pick the host or attendee email.
75 61 $booking->updateMeta('rescheduled_by_type', $rescheduleBy);
76 62
77 63 if ($booking->isMultiGuestBooking()) {
78 - // Need to handle group booking type here
79 - // check for existing group
64 + // Join the existing group at the new time, if any.
80 65 $parent = Booking::where('status', 'scheduled')
81 66 ->where('event_id', $booking->event_id)
82 67 ->where('start_time', $startTime)
83 68 ->orderBy('id', 'ASC')