| @@ -37,12 +37,14 @@ | ||
| 37 | 37 | if ($bookings->isEmpty()) { |
| 38 | 38 | return true; |
| 39 | 39 | } |
| 40 | 40 | |
| 41 | - Booking::whereIn('id', $bookings->pluck('id')) | |
| 42 | - ->update(['status' => 'completed']); | |
| 41 | + foreach ($bookings as $booking) { | |
| 42 | + // Flag each row just before its hook, so a run that dies mid-loop leaves the rest for the next run. | |
| 43 | + if (!Booking::where('id', $booking->id)->where('status', 'scheduled')->update(['status' => 'completed'])) { | |
| 44 | + continue; | |
| 45 | + } | |
| 43 | 46 | |
| 44 | - foreach ($bookings as $booking) { | |
| 45 | 47 | $booking->status = 'completed'; |
| 46 | 48 | do_action('fluent_booking/booking_schedule_completed', $booking, $booking->calendar_event); |
| 47 | 49 | } |
| 48 | 50 | |
| @@ -62,15 +64,19 @@ | ||
| 62 | 64 | if ($bookings->isEmpty()) { |
| 63 | 65 | return true; |
| 64 | 66 | } |
| 65 | 67 | |
| 66 | - Booking::whereIn('id', $bookings->pluck('id')) | |
| 67 | - ->update([ | |
| 68 | + foreach ($bookings as $booking) { | |
| 69 | + // Flag each row just before its hook, so a run that dies mid-loop leaves the rest for the next run. | |
| 70 | + $flagged = Booking::where('id', $booking->id)->where('status', 'pending')->update([ | |
| 68 | 71 | 'status' => 'cancelled', |
| 69 | 72 | 'updated_at' => gmdate('Y-m-d H:i:s'), // phpcs:ignore WordPress.DateTime.RestrictedFunctions.date_date |
| 70 | 73 | ]); |
| 71 | 74 | |
| 72 | - foreach ($bookings as $booking) { | |
| 75 | + if (!$flagged) { | |
| 76 | + continue; | |
| 77 | + } | |
| 78 | + | |
| 73 | 79 | $booking->status = 'cancelled'; |
| 74 | 80 | do_action('fluent_booking/booking_schedule_auto_cancelled', $booking, $booking->calendar_event); |
| 75 | 81 | } |
| 76 | 82 | |
| @@ -93,15 +99,19 @@ | ||
| 93 | 99 | if ($bookings->isEmpty()) { |
| 94 | 100 | return true; |
| 95 | 101 | } |
| 96 | 102 | |
| 97 | - Booking::whereIn('id', $bookings->pluck('id')) | |
| 98 | - ->update([ | |
| 103 | + foreach ($bookings as $booking) { | |
| 104 | + // Flag each row just before its hook, so a run that dies mid-loop leaves the rest for the next run. | |
| 105 | + $flagged = Booking::where('id', $booking->id)->where('status', 'pending')->update([ | |
| 99 | 106 | 'status' => 'cancelled', |
| 100 | 107 | 'updated_at' => gmdate('Y-m-d H:i:s'), // phpcs:ignore WordPress.DateTime.RestrictedFunctions.date_date |
| 101 | 108 | ]); |
| 102 | 109 | |
| 103 | - foreach ($bookings as $booking) { | |
| 110 | + if (!$flagged) { | |
| 111 | + continue; | |
| 112 | + } | |
| 113 | + | |
| 104 | 114 | $booking->status = 'cancelled'; |
| 105 | 115 | do_action('fluent_booking/booking_schedule_auto_cancelled', $booking, $booking->calendar_event); |
| 106 | 116 | } |
| 107 | 117 | |
| @@ -109,14 +119,27 @@ | ||
| 109 | 119 | } |
| 110 | 120 | |
| 111 | 121 | private function maybeAutoExpireCalendars() |
| 112 | 122 | { |
| 113 | - Calendar::query() | |
| 123 | + $calendarIds = Calendar::query() | |
| 114 | 124 | ->where('type', 'event') |
| 115 | 125 | ->where('status', 'active') |
| 116 | 126 | ->whereDoesntHave('events', function ($query) { |
| 117 | 127 | $query->whereIn('status', ['active', 'draft']); |
| 118 | 128 | }) |
| 129 | + ->limit(500) | |
| 130 | + ->pluck('id'); | |
| 131 | + | |
| 132 | + if ($calendarIds->isEmpty()) { | |
| 133 | + return true; | |
| 134 | + } | |
| 135 | + | |
| 136 | + Calendar::whereIn('id', $calendarIds) | |
| 137 | + ->where('type', 'event') | |
| 138 | + ->where('status', 'active') | |
| 139 | + ->whereDoesntHave('events', function ($query) { | |
| 140 | + $query->whereIn('status', ['active', 'draft']); | |
| 141 | + }) | |
| 119 | 142 | ->update(['status' => 'expired']); |
| 120 | 143 | |
| 121 | 144 | return true; |
| 122 | 145 | } |
| @@ -143,9 +166,20 @@ | ||
| 143 | 166 | } |
| 144 | 167 | |
| 145 | 168 | private function maybeAutoDeleteReservations() |
| 146 | 169 | { |
| 147 | - Booking::query() | |
| 170 | + $reservationIds = Booking::query() | |
| 171 | + ->whereIn('event_type', ['single_event', 'group_event']) | |
| 172 | + ->where('status', 'reserved') | |
| 173 | + ->where('start_time', '<=', gmdate('Y-m-d H:i:s', time())) // phpcs:ignore WordPress.DateTime.RestrictedFunctions.date_date | |
| 174 | + ->limit(500) | |
| 175 | + ->pluck('id'); | |
| 176 | + | |
| 177 | + if ($reservationIds->isEmpty()) { | |
| 178 | + return true; | |
| 179 | + } | |
| 180 | + | |
| 181 | + Booking::whereIn('id', $reservationIds) | |
| 148 | 182 | ->whereIn('event_type', ['single_event', 'group_event']) |
| 149 | 183 | ->where('status', 'reserved') |
| 150 | 184 | ->where('start_time', '<=', gmdate('Y-m-d H:i:s', time())) // phpcs:ignore WordPress.DateTime.RestrictedFunctions.date_date |
| 151 | 185 | ->delete(); |