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/SchedulesController.php +55 -6 2.2.0 → 2.5.0 View file →
@@ -15,8 +15,9 @@
15 15 use FluentBooking\App\Services\PermissionManager;
16 16 use FluentBooking\App\Services\CalendarService;
17 17 use FluentBooking\App\Services\ExportHelper;
18 18 use FluentBooking\App\Services\Integrations\FluentCRM\CrmContactService;
19 +use FluentBooking\App\Services\Integrations\FluentCart\CustomerProfileService;
19 20 use FluentCrm\App\Services\PermissionManager as CrmPermissionManager;
20 21
21 22 class SchedulesController extends Controller
22 23 {
@@ -140,9 +141,9 @@
140 141
141 142 $query = Booking::with(['calendar_event']);
142 143
143 144 $hasPermission = PermissionManager::userCanSeeAllBookings();
144 -
145 +
145 146 if (!$hasPermission || $author == 'me') {
146 147 $query->where('host_user_id', get_current_user_id());
147 148 }
148 149
@@ -177,9 +178,9 @@
177 178
178 179 private function addCountsForFirstPage($author, &$data)
179 180 {
180 181 $bookingQuery = Booking::query()
181 - ->when($author == 'me', function($query) {
182 + ->when(!PermissionManager::userCanSeeAllBookings() || $author == 'me', function($query) {
182 183 return $query->where('host_user_id', get_current_user_id());
183 184 })
184 185 ->when($author && is_numeric($author), function($query) use ($author) {
185 186 return $query->where('calendar_id', $author);
@@ -239,10 +240,19 @@
239 240 if (!in_array($value, ['scheduled', 'completed', 'cancelled', 'rejected', 'no_show'])) {
240 241 return $this->sendError(['message' => __('Invalid status', 'fluent-booking')]);
241 242 }
242 243
244 + if (in_array($booking->status, ['cancelled', 'rejected'])) {
245 + return $this->sendError(['message' => __('A cancelled or rejected booking can not be changed', 'fluent-booking')]);
246 + }
247 +
243 248 if ($value == 'scheduled' && $booking->payment_method && $booking->payment_order) {
244 249 $order = $booking->payment_order;
250 +
251 + if (in_array($order->status, ['refunded', 'partially-refunded'])) {
252 + return $this->sendError(['message' => __('A refunded payment can not be marked as paid', 'fluent-booking')]);
253 + }
254 +
245 255 $order->total_paid = $order->total_amount;
246 256 $order->completed_at = gmdate('Y-m-d H:i:s'); // phpcs:ignore WordPress.DateTime.RestrictedFunctions.date_date
247 257 $order->status = 'paid';
248 258 $order->save();
@@ -257,18 +267,24 @@
257 267 do_action('fluent_booking/log_booking_activity', $this->getConfirmLog($booking->id));
258 268 }
259 269
260 270 if ($value == 'cancelled') {
261 - $cancelReason = sanitize_text_field($data['cancel_reason']);
271 + $cancelReason = sanitize_text_field(Arr::get($data, 'cancel_reason', ''));
262 272 $booking->cancelMeeting($cancelReason, 'host', get_current_user_id());
263 273 }
264 274
265 275 if ($value == 'rejected') {
266 - $rejectReason = sanitize_text_field($data['reject_reason']);
276 + $rejectReason = sanitize_text_field(Arr::get($data, 'reject_reason', ''));
267 277 $booking->rejectMeeting($rejectReason, get_current_user_id());
268 278 }
269 279
270 280 if (in_array($value, ['cancelled', 'rejected'])) {
281 + // cancelMeeting() and rejectMeeting() refuse some statuses without changing the booking.
282 + if ($booking->status != $value) {
283 + /* translators: %s: Booking status */
284 + return $this->sendError(['message' => sprintf(__('This booking can not be %s', 'fluent-booking'), $value)]);
285 + }
286 +
271 287 if ($booking->payment_method && Arr::get($data, 'refund_payment') == 'yes') {
272 288 do_action('fluent_booking/refund_payment_' . $booking->payment_method, $booking, $booking->calendar_event);
273 289 }
274 290 return [
@@ -436,8 +452,9 @@
436 452 {
437 453 $this->resolveOwnedBookingOrFail($bookingId);
438 454
439 455 $activities = BookingActivity::where('booking_id', $bookingId)
456 + ->where('type', '!=', BookingActivity::TYPE_NOTE)
440 457 ->orderBy('id', 'DESC')
441 458 ->get();
442 459
443 460 return [
@@ -449,11 +466,12 @@
449 466 {
450 467 $booking = $this->resolveOwnedBookingOrFail($bookingId);
451 468
452 469 $activities = BookingActivity::where('booking_id', $booking->id)
470 + ->where('type', '!=', BookingActivity::TYPE_NOTE)
453 471 ->orderBy('id', 'DESC')
454 472 ->get();
455 -
473 +
456 474 $activities->each(function ($activity) {
457 475 $activity->description = wp_unslash($activity->description);
458 476 });
459 477
@@ -459,9 +477,10 @@
459 477
460 478 $sidebarContents = [];
461 479 $mainBodyContents = [];
462 480
463 - $crmProfile = CrmContactService::getProfileData($booking->email);
481 + $canReadCrm = CrmContactService::isActive() && CrmPermissionManager::currentUserCan('fcrm_read_contacts');
482 + $crmProfile = $canReadCrm ? CrmContactService::getProfileData($booking->email) : null;
464 483 if ($crmProfile) {
465 484 $sidebarContents[] = [
466 485 'id' => 'fluent_crm_profule',
467 486 'title' => __('CRM Profile', 'fluent-booking'),
@@ -469,8 +488,20 @@
469 488 'profile' => $crmProfile,
470 489 ];
471 490 }
472 491
492 + $cartProfile = CustomerProfileService::canView()
493 + ? CustomerProfileService::getProfileData($booking->email)
494 + : null;
495 + if ($cartProfile) {
496 + $sidebarContents[] = [
497 + 'id' => 'fluent_cart_profile',
498 + 'title' => __('Cart Profile', 'fluent-booking'),
499 + 'type' => 'cart_profile',
500 + 'profile' => $cartProfile,
501 + ];
502 + }
503 +
473 504 $order = null;
474 505 if ($booking->payment_status && $booking->payment_order) {
475 506 $order = $booking->payment_order;
476 507 $relations = ['items', 'transaction'];
@@ -505,8 +536,14 @@
505 536 'message' => __('FluentCRM is not active.', 'fluent-booking')
506 537 ]);
507 538 }
508 539
540 + if (!CrmPermissionManager::currentUserCan('fcrm_read_contacts')) {
541 + return $this->sendError([
542 + 'message' => __('You do not have permission to read CRM contacts.', 'fluent-booking')
543 + ], 403);
544 + }
545 +
509 546 $state = CrmContactService::getContactState($booking->email);
510 547
511 548 if (!$state) {
512 549 return $this->sendError([
@@ -593,8 +630,14 @@
593 630 'message' => __('FluentCRM is not active.', 'fluent-booking')
594 631 ]);
595 632 }
596 633
634 + if (!CrmPermissionManager::currentUserCan('fcrm_read_contacts')) {
635 + return $this->sendError([
636 + 'message' => __('You do not have permission to read CRM contacts.', 'fluent-booking')
637 + ], 403);
638 + }
639 +
597 640 $type = $request->get('type') === 'lists' ? 'lists' : 'tags';
598 641 $search = sanitize_text_field($request->get('search', ''));
599 642
600 643 return [
@@ -619,8 +662,14 @@
619 662 if (!CrmContactService::isActive()) {
620 663 return $this->sendError([
621 664 'message' => __('FluentCRM is not active.', 'fluent-booking')
622 665 ]);
666 + }
667 +
668 + if (!CrmPermissionManager::currentUserCan('fcrm_manage_contacts')) {
669 + return $this->sendError([
670 + 'message' => __('You do not have permission to manage CRM contacts.', 'fluent-booking')
671 + ], 403);
623 672 }
624 673
625 674 $requestKey = $type === 'tags' ? 'tag_ids' : 'list_ids';
626 675 $desired = (array) $request->get($requestKey, []);