Bitrix-D7 23.9
 
Загрузка...
Поиск...
Не найдено
util.php
1<?php
2namespace Bitrix\Calendar;
3
13use COption;
14
15class Util
16{
17 public const USER_SELECTOR_CONTEXT = "CALENDAR";
18 public const USER_FIELD_ENTITY_ID = 'CALENDAR_EVENT';
20 public const DATETIME_PHP_FORMAT = 'Y-m-d H:i:sP';
21 public const VERSION_DIFFERENCE = 1;
22 public const DEFAULT_TIMEZONE = "UTC";
23
24 private static $requestUid = '';
25 private static $userAccessCodes = [];
26 private static $pathCache = [];
27 private static $isRussian = null;
28
34 public static function isManagerForUser($managerId, $userId): bool
35 {
36 return in_array('IU'.$userId, self::getUserAccessCodes($managerId));
37 }
38
44 public static function isSectionStructureConverted(): bool
45 {
46 return \Bitrix\Main\Config\Option::get('calendar', 'sectionStructureConverted', 'N') === 'Y';
47 }
48
55 public static function getTimestamp($date, $round = true, $getTime = true)
56 {
57 $timestamp = MakeTimeStamp($date, \CSite::getDateFormat($getTime ? "FULL" : "SHORT"));
58
59 return $round ? (round($timestamp / 60) * 60) : $timestamp;
60 }
61
66 public static function isTimezoneValid(?string $timeZone): bool
67 {
68 return (!is_null($timeZone) && $timeZone !== 'false' && in_array($timeZone, timezone_identifiers_list(), true));
69 }
70
75 public static function prepareTimezone(?string $tz = null): \DateTimeZone
76 {
77 if (!$tz)
78 {
79 return new \DateTimeZone(self::DEFAULT_TIMEZONE);
80 }
81
82 if (self::isTimezoneValid($tz))
83 {
84 return new \DateTimeZone($tz);
85 }
86
88 {
89 return new \DateTimeZone($timezones[0]);
90 }
91
92 return new \DateTimeZone(self::getServerTimezoneName());
93 }
94
102 public static function getDateObject(string $date = null, ?bool $fullDay = true, ?string $tz = 'UTC'): Date
103 {
104 $preparedDate = $date;
105 if ($date)
106 {
107 $timestamp = \CCalendar::Timestamp($date, false, !$fullDay);
108 $preparedDate = \CCalendar::Date($timestamp, !$fullDay);
109 }
110
111 return $fullDay
112 ? new Date($preparedDate, Date::convertFormatToPhp(FORMAT_DATE))
113 : new DateTime($preparedDate, Date::convertFormatToPhp(FORMAT_DATETIME), Util::prepareTimezone($tz));
114 }
115
119 public static function getUserSelectorContext(): string
120 {
122 }
123
124 public static function checkRuZone(): bool
125 {
126 if (!is_null(self::$isRussian))
127 {
128 return self::$isRussian;
129 }
130
131 if (\Bitrix\Main\ModuleManager::isModuleInstalled('bitrix24'))
132 {
133 self::$isRussian = (\CBitrix24::getPortalZone() === 'ru');
134 }
135 else
136 {
137 $iterator = LanguageTable::getList([
138 'select' => ['ID'],
139 'filter' => ['=ID' => 'ru', '=ACTIVE' => 'Y']
140 ]);
141
142 $row = $iterator->fetch();
143 if (empty($row))
144 {
145 self::$isRussian = false;
146 }
147 else
148 {
149 $iterator = LanguageTable::getList([
150 'select' => ['ID'],
151 'filter' => ['@ID' => ['ua', 'by', 'kz'], '=ACTIVE' => 'Y'],
152 'limit' => 1
153 ]);
154 $row = $iterator->fetch();
155 self::$isRussian = empty($row);
156 }
157 }
158
159 return self::$isRussian;
160 }
161
162 public static function convertEntitiesToCodes($entityList = [])
163 {
164 $codeList = [];
165 if (is_array($entityList))
166 {
167 foreach($entityList as $entity)
168 {
169 if ($entity['entityId'] === 'meta-user' && $entity['id'] === 'all-users')
170 {
171 $codeList[] = 'UA';
172 }
173 elseif ($entity['entityId'] === 'user')
174 {
175 $codeList[] = 'U'.$entity['id'];
176 }
177 elseif ($entity['entityId'] === 'project' || $entity['entityId'] === 'project-roles')
178 {
179 $codeList[] = 'SG'.$entity['id'];
180 }
181 elseif ($entity['entityId'] === 'department')
182 {
183 $codeList[] = 'DR'.$entity['id'];
184 }
185 }
186 }
187 return $codeList;
188 }
189
190 public static function convertCodesToEntities($codeList = [])
191 {
192 $entityList = [];
193 if (is_array($codeList))
194 {
195 foreach($codeList as $code)
196 {
197 if ($code === 'UA')
198 {
199 $entityList[] = [
200 'entityId' => 'meta-user',
201 'id' => 'all-users'
202 ];
203 }
204 elseif (mb_substr($code, 0, 1) == 'U')
205 {
206 $entityList[] = [
207 'entityId' => 'user',
208 'id' => intval(mb_substr($code, 1))
209 ];
210 }
211 if (mb_substr($code, 0, 2) == 'DR')
212 {
213 $entityList[] = [
214 'entityId' => 'department',
215 'id' => intval(mb_substr($code, 2))
216 ];
217 }
218 elseif (preg_match('/^SG([0-9]+)_?([AEKMO])?$/', $code, $match) && isset($match[2]))
219 {
220 // todo May need to be removed/rewrite after creating new roles in projects.
221 $entityList[] = [
222 'entityId' => 'project-roles',
223 'id' => mb_substr($code, 2)
224 ];
225 }
226 elseif (mb_substr($code, 0, 2) == 'SG')
227 {
228 $entityList[] = [
229 'entityId' => 'project',
230 'id' => intval(mb_substr($code, 2))
231 ];
232 }
233 }
234 }
235
236 return $entityList;
237 }
238
239 public static function getUsersByEntityList($entityList, $fetchUsers = false)
240 {
241 return \CCalendar::GetDestinationUsers(self::convertEntitiesToCodes($entityList), $fetchUsers);
242 }
243
244
245 public static function getDefaultEntityList($userId, $type, $ownerId)
246 {
247 $entityList = [['entityId' => 'user', 'id' => $userId]];
248 if ($type === 'user' && $ownerId !== $userId)
249 {
250 $entityList[] = ['entityId' => 'user', 'id' => $ownerId];
251 }
252 else if($type === 'group')
253 {
254 $entityList[] = ['entityId' => 'project', 'id' => $ownerId];
255 }
256 return $entityList;
257 }
258
267 public static function getAttendees(array $codeAttendees = null, string $stringWrapper = ''): array
268 {
269 if (empty($codeAttendees))
270 {
271 return [];
272 }
273
274 $userIdList = [];
275 $userList = [];
276
277 foreach ($codeAttendees as $codeAttend)
278 {
279 if (mb_strpos($codeAttend, 'U') === 0)
280 {
281 $userId = (int)(mb_substr($codeAttend, 1));
282 $userIdList[] = $userId;
283 }
284 }
285
286 if (!empty($userIdList))
287 {
288 $res = \Bitrix\Main\UserTable::getList(array(
289 'filter' => [
290 '=ID' => $userIdList,
291 ],
292 'select' => ['NAME', 'LAST_NAME'],
293 ));
294
295 while ($user = $res->fetch())
296 {
297 $userList[] = addcslashes($stringWrapper . $user['NAME'].' '.$user['LAST_NAME'] . $stringWrapper, "()");
298 }
299 }
300
301 return $userList;
302 }
303
312 public static function isExtranetUser(int $userId): bool
313 {
314 if (Loader::includeModule('intranet'))
315 {
316 $userDb = \Bitrix\Intranet\UserTable::getList([
317 'filter' => [
318 'ID' => $userId,
319 ],
320 'select' => [
321 'USER_TYPE',
322 ]
323 ]);
324
325 $user = $userDb->fetch();
326 return $user['USER_TYPE'] === 'extranet';
327 }
328
329 return false;
330 }
331
339 public static function getEventById(int $eventId): ?array
340 {
341 $eventDb = Internals\EventTable::getList([
342 'filter' => [
343 '=ID' => $eventId,
344 ],
345 ]);
346
347 if ($event = $eventDb->fetch())
348 {
349 if (!empty($event['NAME']))
350 {
351 $event['NAME'] = Emoji::decode($event['NAME']);
352 }
353 if (!empty($event['DESCRIPTION']))
354 {
355 $event['DESCRIPTION'] = Emoji::decode($event['DESCRIPTION']);
356 }
357 if (!empty($event['LOCATION']))
358 {
359 $event['LOCATION'] = Emoji::decode($event['LOCATION']);
360 }
361 return $event;
362 }
363
364 return null;
365 }
366
373 public static function addPullEvent(string $command, int $userId, array $params = []): bool
374 {
375 if (!Loader::includeModule("pull"))
376 {
377 return false;
378 }
379
380 if (
381 in_array($command, [
382 'edit_event',
383 'delete_event',
384 'set_meeting_status',
385 ])
386 )
387 {
388 \CPullWatch::AddToStack(
389 'calendar-planner-'.$userId,
390 [
391 'module_id' => 'calendar',
392 'command' => $command,
393 'params' => $params
394 ]
395 );
396 }
397
398 if (
399 in_array($command, [
400 'edit_event',
401 'delete_event',
402 'set_meeting_status',
403 ])
404 && isset($params['fields'])
405 && isset($params['fields']['SECTION_OWNER_ID'])
406 && (int)$params['fields']['SECTION_OWNER_ID'] !== $userId
407 )
408 {
409 \Bitrix\Pull\Event::add(
410 (int)$params['fields']['SECTION_OWNER_ID'],
411 [
412 'module_id' => 'calendar',
413 'command' => $command,
414 'params' => $params
415 ]
416 );
417 }
418
419 return \Bitrix\Pull\Event::add(
420 $userId,
421 [
422 'module_id' => 'calendar',
423 'command' => $command,
424 'params' => $params
425 ]
426 );
427 }
428
435 public static function initPlannerPullWatches(int $currentUserId, array $userIdList = []): void
436 {
437 if (Loader::includeModule("pull"))
438 {
439 foreach($userIdList as $userId)
440 {
441 if ((int)$userId !== $currentUserId)
442 {
443 \CPullWatch::Add($currentUserId, 'calendar-planner-'.$userId);
444 }
445 }
446 }
447 }
448
449 public static function getUserFieldsByEventId(int $eventId): array
450 {
451 global $DB;
452 $result = [];
453 $strSql = "SELECT * from b_uts_calendar_event WHERE VALUE_ID=" . $eventId;
454 $ufDb = $DB->query($strSql);
455
456 while ($uf = $ufDb->fetch())
457 {
458 $result[] = [
459 'crm' => unserialize($uf['UF_CRM_CAL_EVENT'], ['allowed_classes' => false]),
460 'webdav' => unserialize($uf['UF_WEBDAV_CAL_EVENT'], ['allowed_classes' => false]),
461 ];
462 }
463
464 return $result;
465 }
466
470 public static function getServerTimezoneName(): string
471 {
472 return (new \DateTime())->getTimezone()->getName();
473 }
474
478 public static function getServerOffsetUTC(): int
479 {
480 return (new \DateTime())->getOffset();
481 }
482
489 public static function getTimezoneOffsetFromServer(?string $tz = 'UTC', $date = null): int
490 {
491 if ($date instanceof Date)
492 {
493 $timestamp = $date->format(self::DATETIME_PHP_FORMAT);
494 }
495 elseif ($date === null)
496 {
497 $timestamp = 'now';
498 }
499 else
500 {
501 $timestamp = "@".(int)$date;
502 }
503
504 $date = new \DateTime($timestamp, self::prepareTimezone($tz));
505
506 return $date->getOffset() - self::getServerOffsetUTC();
507 }
508
512 public static function setRequestUid(string $requestUid = ''): void
513 {
514 self::$requestUid = $requestUid;
515 }
516
520 public static function getRequestUid(): string
521 {
522 return self::$requestUid;
523 }
524
529 public static function getUserAccessCodes(int $userId): array
530 {
531 global $USER;
532 $userId = (int)$userId;
533 if (!$userId)
534 {
535 $userId = \CCalendar::GetCurUserId();
536 }
537
538 if (!isset(self::$userAccessCodes[$userId]))
539 {
540 $codes = [];
541 $r = \CAccess::GetUserCodes($userId);
542 while($code = $r->Fetch())
543 {
544 $codes[] = $code['ACCESS_CODE'];
545 }
546
547 if (!in_array('G2', $codes))
548 {
549 $codes[] = 'G2';
550 }
551
552 if (!in_array('AU', $codes) && $USER && (int)$USER->GetId() === $userId)
553 {
554 $codes[] = 'AU';
555 }
556
557 if(!in_array('UA', $codes) && $USER && (int)$USER->GetId() == $userId)
558 {
559 $codes[] = 'UA';
560 }
561
562 self::$userAccessCodes[$userId] = $codes;
563 }
564
565 return self::$userAccessCodes[$userId];
566 }
567
568
574 public static function getPathToCalendar(?int $ownerId, ?string $type): string
575 {
576 $key = $type . $ownerId;
577 if (!isset(self::$pathCache[$key]) || !is_string(self::$pathCache[$key]))
578 {
579 if ($type === 'user')
580 {
581 $path = \COption::GetOptionString(
582 'calendar',
583 'path_to_user_calendar',
584 \COption::getOptionString('socialnetwork', 'user_page', "/company/personal/")
585 . "user/#user_id#/calendar/"
586 );
587 }
588 elseif ($type === 'group')
589 {
590 $path = \COption::GetOptionString(
591 'calendar',
592 'path_to_group_calendar',
593 \COption::getOptionString('socialnetwork', 'workgroups_page', "/workgroups/")
594 . "group/#group_id#/calendar/"
595 );
596 }
597 else
598 {
599 $settings = \CCalendar::GetSettings();
600 $path = $settings['path_to_type_' . $type] ?? null;
601 }
602
603 if (!\COption::GetOptionString('calendar', 'pathes_for_sites', true))
604 {
605 $siteId = \CCalendar::GetSiteId();
606 $pathList = \CCalendar::GetPathes();
607 if (isset($pathList[$siteId]))
608 {
609 if ($type === 'user' && isset($pathList[$siteId]['path_to_user_calendar']))
610 {
611 $path = $pathList[$siteId]['path_to_user_calendar'];
612 }
613 elseif ($type === 'group' && isset($pathList[$siteId]['path_to_group_calendar']))
614 {
615 $path = $pathList[$siteId]['path_to_group_calendar'];
616 }
617 else if (!empty($pathList[$siteId]['path_to_type_' . $type]))
618 {
619 $path = $pathList[$siteId]['path_to_type_' . $type];
620 }
621 }
622 }
623
624 if (!is_string($path))
625 {
626 $path = '';
627 }
628
629 if (!empty($path) && $ownerId > 0)
630 {
631 if ($type === 'user')
632 {
633 $path = str_replace(['#user_id#', '#USER_ID#'], $ownerId, $path);
634 }
635 elseif ($type === 'group')
636 {
637 $path = str_replace(['#group_id#', '#GROUP_ID#'], $ownerId, $path);
638 }
639 }
640 self::$pathCache[$key] = $path;
641 }
642
643 return self::$pathCache[$key];
644 }
645
649 public static function getServerName(): string
650 {
651 return COption::getOptionString('main', 'server_name', Application::getInstance()->getContext()->getServer()->getServerName());
652 }
653
659 public static function secondsToDayHoursMinutes(int $second): array
660 {
661 $day = $second / 24 / 3600;
662 $hours = $second / 3600 - (int)$day * 24;
663 $min = $second / 60 - (int)$day * 24 * 60 - (int)$hours * 60;
664
665 return [
666 'days' => (int)$day,
667 'hours' => (int)$hours,
668 'minutes' => (int)$min
669 ];
670 }
671
677 public static function minutesToDayHoursMinutes(int $minutes): array
678 {
679 $day = $minutes / 24 / 60;
680 $hours = $minutes / 60 - (int)$day * 24;
681 $min = $minutes - (int)$day * 24 * 60 - (int)$hours * 60;
682
683 return [
684 'days' => (int)$day,
685 'hours' => (int)$hours,
686 'minutes' => (int)$min
687 ];
688 }
689
690 public static function getDateTimestamp(?string $dateFrom, ?string $timezone): ?int
691 {
692 if (!$dateFrom || !$timezone)
693 {
694 return null;
695 }
696
697 $date = new \Bitrix\Calendar\Core\Base\Date(
699 $dateFrom,
700 false,
701 $timezone
702 )
703 );
704
705 return $date->getTimestamp();
706 }
707
708 public static function formatDateTimeTimestamp(int $timestamp, string $timezoneName): string
709 {
710 $timezone = new \DateTimeZone($timezoneName);
711 $dateTimeFormat = Date::convertFormatToPhp(FORMAT_DATETIME);
712
713 return (new \DateTime('now', $timezone))
714 ->setTimestamp($timestamp)
715 ->format($dateTimeFormat)
716 ;
717 }
718
719 public static function formatDateTimeTimestampUTC(int $timestamp): string
720 {
721 $dateTimeFormat = Date::convertFormatToPhp(FORMAT_DATETIME);
722
723 return gmdate($dateTimeFormat, $timestamp);
724 }
725
726 public static function formatDateTimestampUTC(int $timestamp): string
727 {
728 $dateFormat = Date::convertFormatToPhp(FORMAT_DATE);
729
730 return gmdate($dateFormat, $timestamp);
731 }
732
733 public static function getTimezoneOffsetUTC(string $timezoneName): int
734 {
735 $utc = new \DateTimeZone('UTC');
736
737 return (new \DateTimeZone($timezoneName))->getOffset(new \DateTime('now', $utc));
738 }
739
740 public static function getDateTimestampUtc(DateTime $date, ?string $eventTimezone = null): int
741 {
742 $dateTimezone = $date->getTimeZone()->getName();
743 $dateTimestampUTC = $date->getTimestamp() + \CCalendar::GetTimezoneOffset($dateTimezone);
744 $eventOffsetUTC = \CCalendar::GetTimezoneOffset($eventTimezone);
745
746 return $dateTimestampUTC - $eventOffsetUTC;
747 }
748
749 public static function formatEventDateTime(DateTime $dateTime): string
750 {
751 $culture = Main\Application::getInstance()->getContext()->getCulture();
752 $dayMonthFormat = Main\Type\Date::convertFormatToPhp($culture->getDateFormat());
753 $timeFormat = $culture->get('SHORT_TIME_FORMAT');
754
755 $eventDate = FormatDate($dayMonthFormat, $dateTime->getTimestamp());
756 $eventTime = FormatDate($timeFormat, $dateTime->getTimestamp());
757
758 return "$eventDate $eventTime";
759 }
760
761 public static function getTimezoneHint(int $userId, array $event): string
762 {
763 $skipTime = $event['DT_SKIP_TIME'] === "Y";
764 $timezoneHint = '';
765 if (
766 !$skipTime
767 && (
768 (int)$event['~USER_OFFSET_FROM'] !== 0
769 || (int)$event['~USER_OFFSET_TO'] !== 0
770 || $event['TZ_FROM'] !== $event['TZ_TO']
771 || $event['TZ_FROM'] !== \CCalendar::GetUserTimezoneName($userId)
772 )
773 )
774 {
775 if ($event['TZ_FROM'] === $event['TZ_TO'])
776 {
777 $timezoneHint = \CCalendar::GetFromToHtml(
778 \CCalendar::Timestamp($event['DATE_FROM']),
779 \CCalendar::Timestamp($event['DATE_TO']),
780 false,
781 $event['DT_LENGTH']
782 );
783 if ($event['TZ_FROM'])
784 {
785 $timezoneHint .= ' (' . $event['TZ_FROM'] . ')';
786 }
787 }
788 else
789 {
790 $timezoneHint = Loc::getMessage('EC_VIEW_DATE_FROM_TO', array('#DATE_FROM#' => $event['DATE_FROM'].' ('.$event['TZ_FROM'].')', '#DATE_TO#' => $event['DATE_TO'].' ('.$event['TZ_TO'].')'));
791 }
792 }
793
794 return $timezoneHint;
795 }
796
797 public static function formatEventDate(DateTime $dateTime): string
798 {
799 $culture = Main\Application::getInstance()->getContext()->getCulture();
800 $dayMonthFormat = Main\Type\Date::convertFormatToPhp($culture->getDateFormat());
801
802 return FormatDate($dayMonthFormat, $dateTime->getTimestamp());
803 }
804
805 public static function doIntervalsIntersect($from1, $to1, $from2, $to2): bool
806 {
807 return self::oneIntervalIntersectsAnother($from1, $to1, $from2, $to2)
808 || self::oneIntervalIntersectsAnother($from2, $to2, $from1, $to1);
809 }
810
811 public static function oneIntervalIntersectsAnother($from1, $to1, $from2, $to2): bool
812 {
813 $startsInside = $from2 <= $from1 && $from1 < $to2;
814 $endsInside = $from2 < $to1 && $to1 <= $to2;
815 $startsBeforeEndsAfter = $from1 <= $from2 && $to1 >= $to2;
816
817 return $startsInside || $endsInside || $startsBeforeEndsAfter;
818 }
819}
const VERSION_DIFFERENCE
Definition util.php:21
static isExtranetUser(int $userId)
Definition util.php:312
static oneIntervalIntersectsAnother($from1, $to1, $from2, $to2)
Definition util.php:811
static isSectionStructureConverted()
Definition util.php:44
static getDefaultEntityList($userId, $type, $ownerId)
Definition util.php:245
static minutesToDayHoursMinutes(int $minutes)
Definition util.php:677
static addPullEvent(string $command, int $userId, array $params=[])
Definition util.php:373
static getTimezoneOffsetFromServer(?string $tz='UTC', $date=null)
Definition util.php:489
static getTimezoneHint(int $userId, array $event)
Definition util.php:761
const DEFAULT_TIMEZONE
Definition util.php:22
static formatEventDateTime(DateTime $dateTime)
Definition util.php:749
static getTimezoneOffsetUTC(string $timezoneName)
Definition util.php:733
static getUserSelectorContext()
Definition util.php:119
const USER_SELECTOR_CONTEXT
Definition util.php:17
static getAttendees(array $codeAttendees=null, string $stringWrapper='')
Definition util.php:267
static prepareTimezone(?string $tz=null)
Definition util.php:75
static getEventById(int $eventId)
Definition util.php:339
const DATETIME_PHP_FORMAT
Definition util.php:20
static getServerTimezoneName()
Definition util.php:470
static checkRuZone()
Definition util.php:124
static doIntervalsIntersect($from1, $to1, $from2, $to2)
Definition util.php:805
static isTimezoneValid(?string $timeZone)
Definition util.php:66
static getUsersByEntityList($entityList, $fetchUsers=false)
Definition util.php:239
static getPathToCalendar(?int $ownerId, ?string $type)
Definition util.php:574
static formatDateTimestampUTC(int $timestamp)
Definition util.php:726
static getUserAccessCodes(int $userId)
Definition util.php:529
static getUserFieldsByEventId(int $eventId)
Definition util.php:449
static formatEventDate(DateTime $dateTime)
Definition util.php:797
static getDateObject(string $date=null, ?bool $fullDay=true, ?string $tz='UTC')
Definition util.php:102
static getRequestUid()
Definition util.php:520
static convertEntitiesToCodes($entityList=[])
Definition util.php:162
static secondsToDayHoursMinutes(int $second)
Definition util.php:659
static formatDateTimeTimestampUTC(int $timestamp)
Definition util.php:719
static convertCodesToEntities($codeList=[])
Definition util.php:190
static getDateTimestamp(?string $dateFrom, ?string $timezone)
Definition util.php:690
static getServerName()
Definition util.php:649
static initPlannerPullWatches(int $currentUserId, array $userIdList=[])
Definition util.php:435
static isManagerForUser($managerId, $userId)
Definition util.php:34
const USER_FIELD_ENTITY_ID
Definition util.php:18
static setRequestUid(string $requestUid='')
Definition util.php:512
static formatDateTimeTimestamp(int $timestamp, string $timezoneName)
Definition util.php:708
static getServerOffsetUTC()
Definition util.php:478
static getTimestamp($date, $round=true, $getTime=true)
Definition util.php:55
const LIMIT_NUMBER_BANNER_IMPRESSIONS
Definition util.php:19
static getDateTimestampUtc(DateTime $date, ?string $eventTimezone=null)
Definition util.php:740
static getMessage($code, $replace=null, $language=null)
Definition loc.php:29
static isModuleInstalled($moduleName)
static getList(array $parameters=array())