Bitrix-D7 23.9
 
Загрузка...
Поиск...
Не найдено
accessibility.php
1<?php
2
4
13
15{
16 private bool $checkPermissions = true;
17 private int $skipEventId = 0;
18
19 public function setCheckPermissions(bool $checkPermissions): self
20 {
21 $this->checkPermissions = $checkPermissions;
22
23 return $this;
24 }
25
26 public function setSkipEventId(int $curEventId): self
27 {
28 $this->skipEventId = $curEventId;
29
30 return $this;
31 }
32
39 public function getBusyUsersIds(array $userIds, int $timestampFromUTC, int $timestampToUTC): array
40 {
41 $dateFromTs = \CCalendar::TimestampUTC(Util::formatDateTimestampUTC($timestampFromUTC));
42 $dateToTs = \CCalendar::TimestampUTC(Util::formatDateTimestampUTC($timestampToUTC));
43 $accessibility = $this
44 ->setCheckPermissions(false)
45 ->getAccessibility($userIds, $dateFromTs, $dateToTs)
46 ;
47
48 $busyUsersList = [];
49 $timezoneName = \CCalendar::GetUserTimezoneName(\CCalendar::GetUserId());
50 $timezoneOffset = Util::getTimezoneOffsetUTC($timezoneName);
51 foreach ($accessibility as $userId => $events)
52 {
53 foreach ($events as $accessibilityItem)
54 {
55 $itemFrom = \CCalendar::TimestampUTC($accessibilityItem['from']);
56 $itemTo = \CCalendar::TimestampUTC($accessibilityItem['to']);
57
58 if ($accessibilityItem['isFullDay'])
59 {
60 $itemFrom -= $timezoneOffset;
61 $itemTo -= $timezoneOffset;
62 }
63
64 if (Util::doIntervalsIntersect($timestampFromUTC, $timestampToUTC, $itemFrom, $itemTo))
65 {
66 $busyUsersList[] = $userId;
67 }
68 }
69 }
70
71 return $busyUsersList;
72 }
73
81 public function getAccessibility(array $userIds, int $timestampFromUTC, int $timestampToUTC): array
82 {
83 $accessibility = [];
84
85 if (empty($userIds))
86 {
87 return $accessibility;
88 }
89
90 $events = $this->getEvents($userIds, $timestampFromUTC, $timestampToUTC);
91 $absences = $this->getAbsences($userIds, $timestampFromUTC, $timestampToUTC);
92
93 foreach ($userIds as $userId)
94 {
95 $accessibility[$userId] = array_merge($events[$userId], $absences[$userId]);
96 }
97
98 return $accessibility;
99 }
100
108 public function getEvents(array $userIds, int $timestampFromUTC, int $timestampToUTC): array
109 {
110 [$from, $to] = $this->formatLimitFromTimestamps($timestampFromUTC, $timestampToUTC);
111 $events = \CCalendarEvent::GetList([
112 'arFilter' => [
113 'FROM_LIMIT' => $from,
114 'TO_LIMIT' => $to,
115 'CAL_TYPE' => 'user',
116 'OWNER_ID' => $userIds,
117 'ACTIVE_SECTION' => 'Y'
118 ],
119 'arSelect' => \CCalendarEvent::$defaultSelectEvent,
120 'getUserfields' => false,
121 'parseRecursion' => true,
122 'fetchAttendees' => false,
123 'fetchSection' => true,
124 'parseDescription' => false,
125 'setDefaultLimit' => false,
126 'checkPermissions' => $this->checkPermissions
127 ]);
128
129 $accessibility = $this->initAccessibility($userIds);
130 foreach ($events as $event)
131 {
132 if ((int)$event['ID'] === $this->skipEventId || (int)$event['PARENT_ID'] === $this->skipEventId)
133 {
134 continue;
135 }
136 if ($event['ACCESSIBILITY'] === 'free')
137 {
138 continue;
139 }
140 if ($event['IS_MEETING'] && $event['MEETING_STATUS'] === 'N')
141 {
142 continue;
143 }
144 if (\CCalendarSect::CheckGoogleVirtualSection($event['SECTION_DAV_XML_ID']))
145 {
146 continue;
147 }
148
149 $isFullDay = $event['DT_SKIP_TIME'] === 'Y';
150 if ($isFullDay)
151 {
152 $from = Util::formatDateTimestampUTC(\CCalendar::TimestampUTC($event['DATE_FROM']));
153 $to = Util::formatDateTimestampUTC(\CCalendar::TimestampUTC($event['DATE_TO']) + \CCalendar::GetDayLen());
154 }
155 else
156 {
157 $eventTsFromUTC = Helper::getEventTimestampUTC(new DateTime($event['DATE_FROM']), $event['TZ_FROM']);
158 $eventTsToUTC = Helper::getEventTimestampUTC(new DateTime($event['DATE_TO']), $event['TZ_TO']);
159 $from = Util::formatDateTimeTimestampUTC($eventTsFromUTC);
160 $to = Util::formatDateTimeTimestampUTC($eventTsToUTC);
161 }
162 $accessibility[$event['OWNER_ID']][] = [
163 'id' => $event['ID'],
164 'name' => $this->getEventName($event),
165 'from' => $from,
166 'to' => $to,
167 'isFullDay' => $isFullDay,
168 ];
169 }
170
171 return $accessibility;
172 }
173
174 private function getEventName(array $event): string
175 {
176 if (!$this->canSeeName($event))
177 {
178 return '[' . Loc::getMessage('EC_ACCESSIBILITY_BUSY') . ']';
179 }
180
181 return !empty($event['NAME']) ? $event['NAME'] : Loc::getMessage('EC_T_NEW_EVENT');
182 }
183
184 private function canSeeName(array $event): bool
185 {
186 $currentUserId = \CCalendar::GetUserId();
187 $accessController = new EventAccessController($currentUserId);
188 $eventModel = EventModel::createFromArray($event);
189
190 return !$this->isPrivate($event) && $accessController->check(ActionDictionary::ACTION_EVENT_VIEW_TITLE, $eventModel);
191 }
192
193 private function isPrivate(array $event): bool
194 {
195 $curUserId = \CCalendar::GetUserId();
196
197 return $event['PRIVATE_EVENT'] && $event['CAL_TYPE'] === 'user' && $event['OWNER_ID'] !== $curUserId;
198 }
199
206 public function getAbsences(array $userIds, int $timestampFromUTC, int $timestampToUTC): array
207 {
208 if (!\CCalendar::IsIntranetEnabled())
209 {
210 return [];
211 }
212
213 [$from, $to] = $this->formatLimitFromTimestamps($timestampFromUTC, $timestampToUTC);
214 $usersAbsence = \CIntranetUtils::GetAbsenceData(
215 array(
216 'DATE_START' => $from,
217 'DATE_FINISH' => $to,
218 'USERS' => $userIds,
219 'PER_USER' => true,
220 ),
221 BX_INTRANET_ABSENCE_HR
222 );
223
224 $absenceTypes = \Bitrix\Intranet\UserAbsence::getVacationTypes();
225 $vacationTypes = array_filter(
226 $absenceTypes,
227 fn ($type) => in_array($type['ID'], ['VACATION', 'LEAVESICK', 'LEAVEMATERINITY', 'LEAVEUNPAYED'], true),
228 );
229 $vacationTypesIds = array_map(fn ($type) => (int)$type['ENUM_ID'], $vacationTypes);
230
231 $serverOffset = (int)date('Z');
232 $userOffset = \CCalendar::GetOffset(\CCalendar::GetUserId());
233 $accessibility = $this->initAccessibility($userIds);
234 foreach($usersAbsence as $userId => $absenceData)
235 {
236 foreach($absenceData as $event)
237 {
238 $fromUTC = \CCalendar::TimestampUTC($event['DATE_ACTIVE_FROM']);
239 $toUTC = \CCalendar::TimestampUTC($event['DATE_ACTIVE_TO']);
240 $isFullDay = $this->isFullDay($event['DATE_ACTIVE_FROM'], $event['DATE_ACTIVE_TO']);
241 if ($this->isDateWithoutTimeOrIsMidnight($event['DATE_ACTIVE_TO']))
242 {
243 $toUTC += \CCalendar::GetDayLen();
244 }
245
246 if ($isFullDay)
247 {
248 $from = Util::formatDateTimestampUTC($fromUTC);
249 $to = Util::formatDateTimestampUTC($toUTC);
250 }
251 else
252 {
253 $from = Util::formatDateTimeTimestampUTC($fromUTC - $serverOffset - $userOffset);
254 $to = Util::formatDateTimeTimestampUTC($toUTC - $serverOffset - $userOffset);
255 }
256 $accessibility[$userId][] = [
257 'from' => $from,
258 'to' => $to,
259 'isFullDay' => $isFullDay,
260 'name' => $event['PROPERTY_ABSENCE_TYPE_VALUE'] ?? null,
261 'isVacation' => in_array((int)$event['PROPERTY_ABSENCE_TYPE_ENUM_ID'], $vacationTypesIds, true),
262 ];
263 }
264 }
265
266 return $accessibility;
267 }
268
269 private function isFullDay(string $from, string $to): bool
270 {
271 return $this->isDateWithoutTimeOrIsMidnight($from) && $this->isDateWithoutTimeOrIsMidnight($to);
272 }
273
274 private function isDateWithoutTimeOrIsMidnight(string $date): bool
275 {
276 return \CCalendar::TimestampUTC(Util::formatDateTimeTimestampUTC(\CCalendar::TimestampUTC($date)))
277 === \CCalendar::TimestampUTC(Util::formatDateTimestampUTC(\CCalendar::TimestampUTC($date)));
278 }
279
280 private function formatLimitFromTimestamps(int $timestampFromUTC, int $timestampToUTC): array
281 {
282 return [
283 Util::formatDateTimeTimestampUTC($timestampFromUTC),
284 Util::formatDateTimeTimestampUTC($timestampToUTC)
285 ];
286 }
287
288 private function initAccessibility(array $userIds): array
289 {
290 $accessibility = [];
291 foreach($userIds as $userId)
292 {
293 $accessibility[$userId] = [];
294 }
295
296 return $accessibility;
297 }
298}
getAbsences(array $userIds, int $timestampFromUTC, int $timestampToUTC)
getAccessibility(array $userIds, int $timestampFromUTC, int $timestampToUTC)
getBusyUsersIds(array $userIds, int $timestampFromUTC, int $timestampToUTC)
getEvents(array $userIds, int $timestampFromUTC, int $timestampToUTC)
static getEventTimestampUTC(DateTime $date, ?string $eventTimezone=null)
Definition helper.php:333
static getTimezoneOffsetUTC(string $timezoneName)
Definition util.php:733
static doIntervalsIntersect($from1, $to1, $from2, $to2)
Definition util.php:805
static formatDateTimestampUTC(int $timestamp)
Definition util.php:726
static formatDateTimeTimestampUTC(int $timestamp)
Definition util.php:719
static getMessage($code, $replace=null, $language=null)
Definition loc.php:29