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/Models/Booking.php +31 -14 2.2.5 → 2.5.0 View file →
@@ -1,8 +1,9 @@
1 1 <?php
2 2
3 3 namespace FluentBooking\App\Models;
4 4
5 +use FluentBooking\App\App;
5 6 use FluentBooking\App\Models\Model;
6 7 use FluentBooking\App\Services\BookingFieldService;
7 8 use FluentBooking\App\Services\LocationService;
8 9 use FluentBooking\App\Services\DateTimeHelper;
@@ -137,9 +138,11 @@
137 138 }
138 139
139 140 public static function assignNextGroupId()
140 141 {
141 - $lastEvent = static::orderBy('group_id', 'desc')->first(['group_id']);
142 + // Queue on one row the insert never touches; locking the max row alone deadlocks.
143 + App::getInstance('db')->table('options')->where('option_name', 'fcal_booking_group_lock')->lockForUpdate()->first();
144 + $lastEvent = static::orderBy('group_id', 'desc')->lockForUpdate()->first(['group_id']);
142 145
143 146 return $lastEvent ? $lastEvent->group_id + 1 : 1;
144 147 }
145 148
@@ -168,9 +171,9 @@
168 171 return [];
169 172 }
170 173
171 174 if ($isHtml) {
172 - return wpautop(implode('<br>', $additionalGuests));
175 + return wpautop(implode('<br>', array_map('esc_html', $additionalGuests)));
173 176 }
174 177
175 178 return $additionalGuests;
176 179 }
@@ -400,9 +403,9 @@
400 403 }
401 404
402 405 public function getAllBookingShortTimes($timeZone = 'UTC', $withTimeZone = false)
403 406 {
404 - $otherBookings = self::where('parent_id', $this->id)->get();
407 + $otherBookings = $this->getOwnChildBookings();
405 408
406 409 $otherTimes = $otherBookings->map(function ($otherBooking) use ($timeZone, $withTimeZone) {
407 410 return $otherBooking->formatBookingDateTime($otherBooking->start_time, $timeZone) . ($withTimeZone ? ' (' . $timeZone . ')' : '');
408 411 })->toArray();
@@ -413,9 +416,9 @@
413 416 }
414 417
415 418 public function getAllBookingFullTimes($timeZone = 'UTC', $withTimeZone = false)
416 419 {
417 - $otherBookings = self::where('parent_id', $this->id)->get();
420 + $otherBookings = $this->getOwnChildBookings();
418 421
419 422 $otherTimes = $otherBookings->map(function ($otherBooking) use ($timeZone, $withTimeZone) {
420 423 return $otherBooking->getFullBookingDateTimeText($timeZone) . ($withTimeZone ? ' (' . $timeZone . ')' : '');
421 424 })->toArray();
@@ -424,8 +427,17 @@
424 427 $this->getFullBookingDateTimeText($timeZone) . ($withTimeZone ? ' (' . $timeZone . ')' : '')
425 428 ]);
426 429 }
427 430
431 + /**
432 + * Additional guests on a group booking share the parent link too, each
433 + * with their own email, so only this guest's other times are theirs.
434 + */
435 + private function getOwnChildBookings()
436 + {
437 + return self::where('parent_id', $this->id)->where('email', $this->email)->get();
438 + }
439 +
428 440 public function getHostAndGuestDetailsHtml()
429 441 {
430 442 $authors = $this->getHostsDetails();
431 443
@@ -443,13 +455,13 @@
443 455 $authorListHtml = '<ul class="fcal_listed">';
444 456
445 457 foreach ($authors as $author) {
446 458 $authorBadge = ($author['id'] == $hostUserId) ? '<span class="fcal_host_badge">' . __('Host', 'fluent-booking') . '</span>' : '';
447 - $authorListHtml .= '<li class="fcal_host_name">' . $author['name'] . $authorBadge . '</li>';
459 + $authorListHtml .= '<li class="fcal_host_name">' . esc_html($author['name']) . $authorBadge . '</li>';
448 460 }
449 461
450 462 foreach ($guestNames as $guestName) {
451 - $authorListHtml .= '<li class="fcal_guest_name">' . $guestName . '</li>';
463 + $authorListHtml .= '<li class="fcal_guest_name">' . esc_html($guestName) . '</li>';
452 464 }
453 465 $authorListHtml .= '</ul>';
454 466
455 467 return $authorListHtml;
@@ -642,9 +654,9 @@
642 654 if ($isText) {
643 655 return $row->description;
644 656 }
645 657 if ($isHtml) {
646 - return wp_unslash($row->description);
658 + return esc_html(wp_unslash($row->description));
647 659 }
648 660 }
649 661
650 662 return $row;
@@ -660,9 +672,9 @@
660 672 if ($isText) {
661 673 return $row->description;
662 674 }
663 675 if ($isHtml) {
664 - return wp_unslash($row->description);
676 + return esc_html(wp_unslash($row->description));
665 677 }
666 678 }
667 679
668 680 return $row;
@@ -803,10 +815,15 @@
803 815 $bookingTitle = EditorShortCodeParser::parse($bookingTitle, $this);
804 816
805 817 $bookingTitle = $bookingTitle ?: $this->generateBookingTitle($eventTitle, $authorName, $guestName);
806 818
807 - if ($html && strpos($bookingTitle, $eventTitle) !== false) {
808 - $bookingTitle = str_replace($eventTitle, "<strong>{$eventTitle}</strong>", $bookingTitle);
819 + if ($html) {
820 + $bookingTitle = esc_html($bookingTitle);
821 + $eventTitle = esc_html($eventTitle);
822 +
823 + if (strpos($bookingTitle, $eventTitle) !== false) {
824 + $bookingTitle = str_replace($eventTitle, "<strong>{$eventTitle}</strong>", $bookingTitle);
825 + }
809 826 }
810 827
811 828 return apply_filters('fluent_booking/booking_meeting_title', $bookingTitle, $authorName, $guestName, $calendarEvent, $this);
812 829 }
@@ -1117,9 +1134,9 @@
1117 1134 if ($message) {
1118 1135 return $message;
1119 1136 }
1120 1137
1121 - return __('Sorry! you can not cancel this', 'fluent-booking');
1138 + return __('Sorry! you cannot cancel this', 'fluent-booking');
1122 1139 }
1123 1140
1124 1141 public function getRescheduleMessage()
1125 1142 {
@@ -1130,9 +1147,9 @@
1130 1147 if ($message) {
1131 1148 return $message;
1132 1149 }
1133 1150
1134 - return __('Sorry! you can not reschedule this', 'fluent-booking');
1151 + return __('Sorry! you cannot reschedule this', 'fluent-booking');
1135 1152 }
1136 1153
1137 1154 public function getHostDetails($isPublic = true, $hostId = null)
1138 1155 {
@@ -1250,9 +1267,9 @@
1250 1267 if (empty($data['value'])) {
1251 1268 continue;
1252 1269 }
1253 1270 $html .= '<tr>';
1254 - $html .= '<td><b>' . $data['label'] . '</b></td>';
1271 + $html .= '<td><b>' . esc_html($data['label']) . '</b></td>';
1255 1272 $html .= '<td>' . $data['value'] . '</td>';
1256 1273 $html .= '</tr>';
1257 1274 }
1258 1275 $html .= '</table>';
@@ -1357,5 +1374,5 @@
1357 1374 ]
1358 1375 ], $this);
1359 1376 }
1360 1377
1361 -}
1378 +}