30 private static ?
self $instance;
35 self::$instance ??=
new self();
37 return self::$instance;
47 $canAttend = EventAccessController::can(
49 ActionDictionary::ACTION_OPEN_EVENT_ATTEND,
50 $setEventAttendeeStatusDto->eventId
57 $existEventAttendee = EventAttendeeTable::query()
58 ->addSelect(
'*',
'EVENT')
60 ->where(
'EVENT_ID', $setEventAttendeeStatusDto->eventId)
63 if (($existEventAttendee?->getMeetingStatus() ===
'Y') === $setEventAttendeeStatusDto->attendeeStatus)
68 $locker = Application::getConnection(EventAttendeeTable::getConnectionName());
69 $lockName = sprintf(
'open_event_attend_lock_%d', $setEventAttendeeStatusDto->eventId);
73 $isLocked = $locker->lock($lockName, 10);
76 throw new EventBusyException();
79 $eventMapper = $this->mapperFactory->getEvent();
81 $event = $eventMapper->getById($setEventAttendeeStatusDto->eventId);
83 $maxAttendees =
$event->getEventOption()?->getOptions()?->maxAttendees ?? 0;
86 if ($maxAttendees > 0 && $setEventAttendeeStatusDto->attendeeStatus)
88 $attendeesCount = EventRepository::getEventAttendeesCount($setEventAttendeeStatusDto->eventId);
90 if ($attendeesCount >=
$event->getEventOption()->getOptions()->maxAttendees)
92 throw new MaxAttendeesReachedException();
96 $this->setAttendee(
$userId,
$event, $setEventAttendeeStatusDto->attendeeStatus, $existEventAttendee);
100 $locker->unlock($lockName);
103 $imIntegrationService = ServiceLocator::getInstance()->get(Integration\Im\EventCategoryServiceInterface::class);
105 if ($setEventAttendeeStatusDto->attendeeStatus && !$imIntegrationService->hasAccess(
$userId,
$channelId))
110 \CCalendar::ClearCache([
'event_list']);
113 private function setAttendee(
116 bool $attendeeStatus,
117 ?EventAttendee $existEventAttendee =
null
122 $connection = Application::getInstance()->getConnection();
128 $meetingStatus = $attendeeStatus ?
'Y' :
'N';
129 if (!$existEventAttendee)
131 EventAttendeeTable::add([
134 'MEETING_STATUS' => $meetingStatus,
135 'EVENT_ID' =>
$event->getId(),
136 'SECTION_ID' =>
$event->getSection()->getId(),
138 (
new \Bitrix\Calendar\Core\Mappers\Event())->convertToArray(
$event)[
'REMIND'])
144 $existEventAttendee->setDeleted(!$attendeeStatus);
145 $existEventAttendee->setMeetingStatus($meetingStatus);
146 $existEventAttendee->save();
149 $eventOptions =
$event->getEventOption();
150 $increment = $attendeeStatus ? 1 : -1;
151 $incrementStr = $attendeeStatus ?
'+ 1' :
'- 1';
153 $updateResult = OpenEventOptionTable::update($eventOptions->getId(), [
154 'ATTENDEES_COUNT' =>
new SqlExpression(
'?# ' . $incrementStr,
'ATTENDEES_COUNT'),
157 if (!$updateResult->isSuccess())
160 throw new SystemException(
'failed to update event options');
166 $eventOptions->setAttendeesCount($eventOptions->getAttendeesCount() + $increment);
168 OpenEventPullService::getInstance()->updateCalendarEvent(
172 isAttendee: $attendeeStatus,
186 $this->updateEventSearchableContent(
$event);
189 private function __construct()
191 $this->mapperFactory = ServiceLocator::getInstance()->get(
'calendar.service.mappers.factory');
194 private function updateEventSearchableContent(Event
$event): void
199 'checkPermission' =>
false,
200 'fetchAttendees' =>
true,
208 'NAME' =>
$event->getName(),
209 'DESCRIPTION' =>
$event->getDescription(),
210 'LOCATION' =>
$event->getLocation(),
211 'IS_MEETING' =>
true,
212 'ATTENDEE_LIST' => $attendeeListData[
'attendeeList'][
$event->getId()] ?? [],