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/Http/Controllers/BookingController.php +102 -2 2.2.5 → 2.5.0 View file →
@@ -5,8 +5,9 @@
5 5 use FluentBooking\App\App;
6 6 use FluentBooking\App\Models\Booking;
7 7 use FluentBooking\App\Models\CalendarSlot;
8 8 use FluentBooking\App\Services\BookingService;
9 +use FluentBooking\App\Services\RescheduleService;
9 10 use FluentBooking\App\Services\DateTimeHelper;
10 11 use FluentBooking\App\Services\BookingFieldService;
11 12 use FluentBooking\App\Hooks\Handlers\FrontEndHandler;
12 13 use FluentBooking\App\Hooks\Handlers\TimeSlotServiceHandler;
@@ -196,9 +197,17 @@
196 197 $bookingData['source_url'] = sanitize_url($sourceUrl);
197 198 }
198 199
199 200 if ($hostUserId = Arr::get($postedData, 'host_user_id', null)) {
200 - $bookingData['host_user_id'] = (int) $hostUserId;
201 + $hostUserId = (int) $hostUserId;
202 +
203 + if (!in_array($hostUserId, array_map('intval', $calendarEvent->getHostIds()), true)) {
204 + return $this->sendError([
205 + 'message' => __('The selected host is not a host of this event', 'fluent-booking')
206 + ], 422);
207 + }
208 +
209 + $bookingData['host_user_id'] = $hostUserId;
201 210 }
202 211
203 212 $hostIds = null;
204 213 if ($calendarEvent->isRoundRobin() && !$hostUserId) {
@@ -305,9 +314,19 @@
305 314
306 315 $duration = $calendarEvent->getDuration($request->get('duration'));
307 316
308 317 $hostId = $request->get('host_id', null);
309 -
318 +
319 + if ($hostId) {
320 + $hostId = (int) $hostId;
321 +
322 + if (!in_array($hostId, array_map('intval', $calendarEvent->getHostIds()), true)) {
323 + wp_send_json([
324 + 'message' => __('The selected host is not a host of this event', 'fluent-booking')
325 + ], 422);
326 + }
327 + }
328 +
310 329 $timeSlotService = TimeSlotServiceHandler::initService($calendar, $calendarEvent);
311 330
312 331 if (is_wp_error($timeSlotService)) {
313 332 return TimeSlotServiceHandler::sendError($timeSlotService, $calendarEvent, $timeZone);
@@ -382,8 +401,89 @@
382 401
383 402 return [
384 403 'bookings' => $formattedBookings,
385 404 'total' => $totalBookings
405 + ];
406 + }
407 +
408 + public function getRescheduleSlots(Request $request, $eventId, $bookingId)
409 + {
410 + return $this->getEvent($request, $eventId);
411 + }
412 +
413 + public function rescheduleBooking(Request $request, $eventId, $bookingId)
414 + {
415 + $booking = Booking::with(['calendar_event'])->findOrFail($bookingId);
416 +
417 + $data = $request->all();
418 +
419 + $this->validate($data, [
420 + 'event_time' => 'required',
421 + 'timezone' => 'required'
422 + ], [
423 + 'event_time.required' => __('Please select a date and time', 'fluent-booking'),
424 + 'timezone.required' => __('Please select the timezone', 'fluent-booking')
425 + ]);
426 +
427 + $calendarEvent = $booking->calendar_event;
428 +
429 + if (!$calendarEvent || (int) $calendarEvent->id !== (int) $eventId) {
430 + return $this->sendError(['message' => __('The event of this booking was not found', 'fluent-booking')], 422);
431 + }
432 +
433 + if (!in_array($booking->status, ['scheduled', 'pending', 'approved', 'rescheduled'], true)) {
434 + return $this->sendError(['message' => __('This booking can not be rescheduled', 'fluent-booking')], 422);
435 + }
436 +
437 + $timezone = sanitize_text_field(Arr::get($data, 'timezone'));
438 +
439 + if (!in_array($timezone, \DateTimeZone::listIdentifiers(), true)) {
440 + return $this->sendError(['message' => __('Please select a valid timezone', 'fluent-booking')], 422);
441 + }
442 +
443 + $eventTime = sanitize_text_field(Arr::get($data, 'event_time'));
444 +
445 + if (!\DateTime::createFromFormat('Y-m-d H:i:s', $eventTime)) {
446 + return $this->sendError(['message' => __('Please select a valid date and time', 'fluent-booking')], 422);
447 + }
448 +
449 + $startTime = DateTimeHelper::convertToUtc($eventTime, $timezone);
450 + $endTime = gmdate('Y-m-d H:i:s', strtotime($startTime) + ($booking->slot_minutes * 60)); // phpcs:ignore WordPress.DateTime.RestrictedFunctions.date_date
451 +
452 + $hostUserId = null;
453 +
454 + if (!Arr::isTrue($data, 'ignore_availability')) {
455 + $timeSlotService = TimeSlotServiceHandler::initService($calendarEvent->calendar, $calendarEvent);
456 +
457 + if (is_wp_error($timeSlotService)) {
458 + return $this->sendError(['message' => $timeSlotService->get_error_message()], 422);
459 + }
460 +
461 + $isSlotLocked = Helper::lockRoundRobinSlot($calendarEvent, $startTime, $endTime);
462 +
463 + if (!$isSlotLocked || !$timeSlotService->isSpotAvailable($startTime, $endTime, $booking->slot_minutes)) {
464 + return $this->sendError([
465 + 'message' => __('This selected time slot is not available. Maybe someone booked the spot just a few seconds ago.', 'fluent-booking')
466 + ], 422);
467 + }
468 +
469 + if ($calendarEvent->isRoundRobin()) {
470 + $hostUserId = $timeSlotService->hostUserId;
471 + }
472 + }
473 +
474 + $result = RescheduleService::reschedule($booking, $calendarEvent, $startTime, $timezone, [
475 + 'reason' => Arr::get($data, 'reason', ''),
476 + 'host_user_id' => $hostUserId,
477 + 'source' => __('Admin Panel', 'fluent-booking')
478 + ]);
479 +
480 + if (is_wp_error($result)) {
481 + return $this->sendError(['message' => $result->get_error_message()], 422);
482 + }
483 +
484 + return [
485 + 'message' => __('Booking has been rescheduled', 'fluent-booking')
386 486 ];
387 487 }
388 488
389 489 private static function sanitize_mapped_data($settings)