Bitrix-D7 23.9
 
Загрузка...
Поиск...
Не найдено
helper.php
1<?php
2
3
5
6
14use Bitrix\Disk\Uf\FileUserType;
17use Bitrix\Main\Entity\ReferenceField;
25use COption;
26use DateTimeZone;
29use \Bitrix\Disk\AttachedObject;
30
31IncludeModuleLangFile($_SERVER['DOCUMENT_ROOT'] . BX_ROOT . '/modules/calendar/classes/general/calendar.php');
32
33class Helper
34{
35 public const ICAL_DATETIME_FORMAT_UTC = 'Ymd\THis\Z';
36 public const ICAL_DATETIME_FORMAT = 'Ymd\THis';
37 public const ICAL_DATETIME_FORMAT_SHORT = 'Ymd\THis';
38 public const ICAL_DATE_FORMAT = 'Ymd';
39 public const END_OF_TIME = "01.01.2038";
40
46 public static function getIcalTemplateDate(array $params = null): string
47 {
48 $from = self::getDateObject($params['DATE_FROM'], false, $params['TZ_FROM']);
49 $to = self::getDateObject($params['DATE_TO'], false, $params['TZ_TO']);
50 if ($from->format('dmY') !== $to->format('dmY'))
51 {
52 $res = $params['FULL_DAY']
53 ? $from->format('d.m.Y') . ' - ' . $to->format('d.m.Y')
54 : $from->format('d.m.Y H:i') . ' - ' . $to->format('d.m.Y H:i');
55 }
56 else
57 {
58 $res = $params['FULL_DAY']
59 ? $from->format('d.m.Y')
60 : $from->format('d.m.Y H:i') . ' - ' . $to->format('H:i');
61 }
62
63 return $res;
64 }
65
73 public static function getDateObject(string $date = null, $fullDay = true, $tz = 'UTC'): Date
74 {
75 $preparedDate = $date;
76 if ($date)
77 {
78 $timestamp = \CCalendar::Timestamp($date, false, !$fullDay);
79 $preparedDate = \CCalendar::Date($timestamp);
80 }
81
82 return $fullDay
83 ? new Date($preparedDate, Date::convertFormatToPhp(FORMAT_DATE))
84 : new DateTime($preparedDate, Date::convertFormatToPhp(FORMAT_DATETIME), Util::prepareTimezone($tz));
85 }
86
92 public static function getIcalTemplateRRule(array $rrule = null, array $params = null): string
93 {
94 $res = '';
95 if ($rrule['BYDAY'] ?? false)
96 {
97 $rrule['BYDAY'] = \CCalendarEvent::sortByDay($rrule['BYDAY']);
98 }
99 switch($rrule['FREQ'] ?? null)
100 {
101 case 'DAILY':
102 $res = (int)$rrule['INTERVAL'] === 1
103 ? Loc::getMessage('EC_RRULE_EVERY_DAY')
104 : Loc::getMessage('EC_RRULE_EVERY_DAY_1', ['#DAY#' => $rrule['INTERVAL']])
105 ;
106 break;
107 case 'WEEKLY':
108 if (!isset($rrule['BYDAY']) || !is_array($rrule['BYDAY']))
109 {
110 $rrule['BYDAY'] = ['MO'];
111 }
112
113 $daysList = implode(', ', array_map(static function($day) {return Loc::getMessage('EC_' . $day);}, $rrule['BYDAY']));
114 $res = (int)$rrule['INTERVAL'] === 1
115 ? Loc::getMessage('EC_RRULE_EVERY_WEEK', ['#DAYS_LIST#' => $daysList])
116 : Loc::getMessage('EC_RRULE_EVERY_WEEK_1', ['#WEEK#' => $rrule['INTERVAL'], '#DAYS_LIST#' => $daysList])
117 ;
118 break;
119 case 'MONTHLY':
120 $res = (int)$rrule['INTERVAL'] === 1
121 ? Loc::getMessage('EC_RRULE_EVERY_MONTH')
122 : Loc::getMessage('EC_RRULE_EVERY_MONTH_1', ['#MONTH#' => $rrule['INTERVAL']])
123 ;
124 break;
125 case 'YEARLY':
126 $fromTs = \CCalendar::Timestamp($params['DATE_FROM']);
127 $res = (int)$rrule['INTERVAL'] === 1
128 ? Loc::getMessage('EC_RRULE_EVERY_YEAR', [
129 '#DAY#' => FormatDate('j', $fromTs),
130 '#MONTH#' => FormatDate('n', $fromTs)
131 ])
132 : Loc::getMessage('EC_RRULE_EVERY_YEAR_1', [
133 '#YEAR#' => $rrule['INTERVAL'],
134 '#DAY#' => FormatDate('j', $fromTs),
135 '#MONTH#' => FormatDate('n', $fromTs)
136 ])
137 ;
138 break;
139 }
140
141 if ($rrule['COUNT'] ?? false)
142 {
143 $res .= ' ' . Loc::getMessage('EC_RRULE_COUNT', ['#COUNT#' => $rrule['COUNT']]);
144 }
145 elseif (isset($rrule['UNTIL']) && $rrule['UNTIL'] && self::isNotEndOfTime($rrule['UNTIL']))
146 {
147 $res .= ' ' . Loc::getMessage('EC_RRULE_UNTIL', ['#UNTIL_DATE#' => $rrule['UNTIL']]);
148 }
149
150 if (!is_string($res))
151 {
152 $res = '';
153 }
154
155 return $res;
156 }
157
161 public static function getUniqId(): string
162 {
163 return uniqid(self::getServerName(), true);
164 }
165
169 public static function getServerName()
170 {
171 return COption::getOptionString('main', 'server_name', Application::getInstance()->getContext()->getServer()->getServerName());
172 }
173
178 public static function getTimezoneObject(string $tz = null): DateTimeZone
179 {
180 return !$tz
181 ? (new \DateTime())->getTimezone()
182 : new DateTimeZone(Util::prepareTimezone($tz)->getName());
183 }
184
193 public static function getEventByUId(?string $uid): ?array
194 {
195 if (is_null($uid))
196 {
197 return null;
198 }
199
200 $event = EventTable::getList([
201 'filter' => [
202 '=DAV_XML_ID' => $uid,
203 '=DELETED' => 'N',
204 ],
205 'limit' => 1,
206 ])->fetch();
207
208 return (!empty($event) && is_array($event))
209 ? $event
210 : null;
211 }
212
220 public static function getUserById(?int $id): ?array
221 {
222 if ($id === null)
223 {
224 return null;
225 }
226
227 $user = UserTable::getList([
228 'filter' => [
229 'ID' => $id,
230 ],
231 'select' => [
232 'ID',
233 'NAME',
234 'LAST_NAME',
235 'EMAIL',
236 ],
237 'limit' => 1,
238 ])->fetch();
239
240 return (!empty($user) && is_array($user))
241 ? $user
242 : null;
243 }
244
252 public static function getIndexUsersByIds(?array $idList): array
253 {
254 $usersDb = UserTable::getList([
255 'filter' => [
256 'ID' => $idList,
257 ],
258 'select' => [
259 'ID',
260 'NAME',
261 'LAST_NAME',
262 'EMAIL',
263 ],
264 ]);
265
266 $collection = [];
267 while ($user = $usersDb->fetch())
268 {
269 $collection[$user['ID']] = $user;
270 }
271
272 return $collection;
273 }
274
278 public static function getSaltForPubLink(): string
279 {
280 if($salt = \COption::GetOptionString('calendar', 'pub_event_salt'))
281 {
282 return $salt;
283 }
284
285 $salt = uniqid('', true);
286 \COption::SetOptionString('calendar', 'pub_event_salt', $salt);
287 return $salt;
288 }
289
296 public static function getHashForPubEvent(int $eventId, int $userId, int $dateCreateTimestamp): string
297 {
298 return md5($eventId.self::getSaltForPubLink().$dateCreateTimestamp.$userId);
299 }
300
307 public static function getPubEventLink(int $eventId, int $userId, int $dateCreateTimestamp): string
308 {
309 $context = \Bitrix\Main\Application::getInstance()->getContext();
310 $scheme = $context->getRequest()->isHttps() ? 'https' : 'http';
311 $server = $context->getServer();
312 $domain = $server->getServerName() ?: \COption::getOptionString('main', 'server_name', '');
313
314 if (preg_match('/^(?<domain>.+):(?<port>\d+)$/', $domain, $matches))
315 {
316 $domain = $matches['domain'];
317 $port = $matches['port'];
318 }
319 else
320 {
321 $port = $server->getServerPort();
322 }
323
324 $port = in_array((int)$port, [80, 443], true) ? '' : ":{$port}";
325
326 return "{$scheme}://{$domain}{$port}/pub/calendar-event/{$eventId}/".self::getHashForPubEvent($eventId, $userId, $dateCreateTimestamp)."/";
327 }
328
335 public static function getDetailLink(int $eventId, int $userId, int $dateCreateTimestamp): string
336 {
337 return self::getPubEventLink($eventId, $userId, $dateCreateTimestamp);
338 }
339
347 public static function getPubEventLinkWithParameters(int $eventId, int $userId, int $dateCreateTimestamp, string $decision): string
348 {
349 return self::getDetailLink($eventId, $userId, $dateCreateTimestamp) . "?decision={$decision}";
350 }
351
362 public static function getMailAttaches($fields, $userId, $parentId, &$isChangeFiles = false): AttachCollection
363 {
364 //TODO: need refactoring
365 global $USER_FIELD_MANAGER;
366 $attachCollection = new AttachCollection();
367 $UF = $USER_FIELD_MANAGER->GetUserFields("CALENDAR_EVENT", $parentId, LANGUAGE_ID);
368 $attachedFilesIds = $UF['UF_WEBDAV_CAL_EVENT']['VALUE'];
369
370 $fields['UF_WEBDAV_CAL_EVENT'] ??= null;
371 if (is_array($fields) && is_array($fields['UF_WEBDAV_CAL_EVENT']) && is_array($attachedFilesIds))
372 {
373 $ufIds = array_unique(array_merge($fields['UF_WEBDAV_CAL_EVENT'], $attachedFilesIds));
374 }
375 elseif(is_array($fields) && is_array($fields['UF_WEBDAV_CAL_EVENT']))
376 {
377 $ufIds = $fields['UF_WEBDAV_CAL_EVENT'];
378 }
379 elseif(is_array($attachedFilesIds))
380 {
381 $ufIds = $attachedFilesIds;
382 }
383 else
384 {
385 return $attachCollection;
386 }
387
388 if (!empty($ufIds) && \Bitrix\Main\Loader::includeModule('disk'))
389 {
390 foreach ($ufIds as $item)
391 {
392 [$type, $realValue] = \Bitrix\Disk\Uf\FileUserType::detectType($item);
393
394 if ($type == FileUserType::TYPE_ALREADY_ATTACHED)
395 {
396 $attachedModel = AttachedObject::loadById($realValue);
397 if(!$attachedModel
398 || (!empty($fields['UF_WEBDAV_CAL_EVENT'])
399 && $item !== ''
400 && !in_array($item, $fields['UF_WEBDAV_CAL_EVENT'])))
401 {
402 $isChangeFiles = true;
403 continue;
404 }
405 $file = $attachedModel->getFile();
406 }
407 elseif ($type == \Bitrix\Disk\Uf\FileUserType::TYPE_NEW_OBJECT)
408 {
409 $isChangeFiles = true;
410 $file = \Bitrix\Disk\File::loadById($realValue, ['STORAGE']);
411 }
412
413 if (!$file)
414 {
415 continue;
416 }
417
418 $externalLink = $file->addExternalLink([
419 'CREATED_BY' => $userId,
420 'TYPE' => \Bitrix\Disk\Internals\ExternalLinkTable::TYPE_MANUAL,
421 ]);
422 if (!$externalLink)
423 {
424 continue;
425 }
426
427 $name = $file->getName();
428 $size = $file->getSize();
429 $link = \Bitrix\Disk\Driver::getInstance()->getUrlManager()->getUrlExternalLink([
430 'hash' => $externalLink->getHash(),
431 'action' => 'downloadFile',
432 ],
433 true
434 );
435
436 $attach = Attach::createInstance($link, $name, $size);
437
438 $attachCollection->add($attach);
439 }
440 }
441
442 return $attachCollection;
443 }
444
450 public static function getAttendee(int $userId, int $eventParentId, $isRsvp = true): ?Attendee
451 {
452 $query = EventTable::query()
453 ->setSelect([
454 'MEETING_STATUS',
455 'USER_NAME' => 'USER.NAME',
456 'USER_LAST_NAME' => 'USER.LAST_NAME',
457 'USER_EMAIL' => 'USER.EMAIL',
458 ])
459 ->registerRuntimeField(
460 'USER',
461 new ReferenceField(
462 'USER',
463 UserTable::getEntity(),
464 Join::on('this.OWNER_ID', 'ref.ID'),
465 ['join_type' => Join::TYPE_INNER]
466 )
467 )
468 ->setFilter(['USER.ID'=>$userId, '=PARENT_ID'=>$eventParentId])
469 ;
470
471 $attendee = $query->fetch();
472
473 if (is_null($attendee))
474 {
475 return null;
476 }
477
478 return Attendee::createInstance(
479 $attendee['USER_EMAIL'],
480 $attendee['USER_NAME'],
481 $attendee['USER_LAST_NAME'],
482 Dictionary::ATTENDEE_STATUS[$attendee['MEETING_STATUS']],
483 Dictionary::ATTENDEE_ROLE['REQ_PARTICIPANT'],
484 Dictionary::ATTENDEE_CUTYPE['individual'],
485 $attendee['USER_EMAIL'],
486 $isRsvp
487 );
488 }
489
494 public static function getAttendeesByEventParentId(int $parentId): AttendeesCollection
495 {
496 global $DB;
497 $attendeesCollection = AttendeesCollection::createInstance();
498 $attendeesDb = $DB->query('select event.MEETING_STATUS, user.NAME, user.LAST_NAME, user.EMAIL from b_calendar_event as event JOIN b_user as user ON event.OWNER_ID = user.ID where event.PARENT_ID = '. $parentId);
499 while ($attendee = $attendeesDb->fetch())
500 {
501 $attendeesCollection->add(Attendee::createInstance(
502 $attendee['EMAIL'],
503 $attendee['NAME'],
504 $attendee['LAST_NAME'],
505 Dictionary::ATTENDEE_STATUS[$attendee['MEETING_STATUS']],
506 Dictionary::ATTENDEE_ROLE['REQ_PARTICIPANT'],
507 Dictionary::ATTENDEE_CUTYPE['individual'],
508 $attendee['EMAIL']
509 ));
510 }
511
512 return $attendeesCollection;
513 }
514
521 public static function getIcalDateTime(string $dateTime = null, string $tz = null): DateTime
522 {
524
525 return new DateTime($dateTime, $format, Util::prepareTimezone($tz));
526 }
527
533 public static function getIcalDate(string $date = null): Date
534 {
535 return new Date($date, self::ICAL_DATE_FORMAT);
536 }
537
545 public static function getUserIdByEmail(array $userInfo): ?int
546 {
547 $parameters = [
548 'filter' => [
549 'EMAIL' => $userInfo['EMAIL'],
550 ],
551 'select' => ['ID',],
552 'limit' => 1,
553 ];
554
555 $userDd = UserTable::getList($parameters);
556 if ($user = $userDd->fetch())
557 {
558 return (int)$user['ID'];
559 }
560
561 return self::getExternalUserByEmail($userInfo, $errorCollection);
562 }
563
574 public static function getExternalUserByEmail($params, &$errorText): ?int
575 {
576 $userId = null;
577 $user = null;
578
579 if (
580 !is_array($params)
581 || empty($params['EMAIL'])
582 || !check_email($params['EMAIL'])
583 || !Loader::includeModule('mail')
584 )
585 {
586 return $userId;
587 }
588
589 $userEmail = $params['EMAIL'];
590
591 if (
592 empty($userEmail)
593 || !check_email($userEmail)
594 )
595 {
596 return $userId;
597 }
598
599 $res = \CUser::getList(
600 $o = "ID",
601 $b = "ASC",
602 [
603 "=EMAIL" => $userEmail,
604 "!EXTERNAL_AUTH_ID" => \Bitrix\Main\UserTable::getExternalUserTypes(),
605 ],
606 [
607 "FIELDS" => [ "ID", "EXTERNAL_AUTH_ID", "ACTIVE" ]
608 ]
609 );
610
611 while (($emailUser = $res->fetch()) && !$userId)
612 {
613 if (
614 (int)$emailUser["ID"] > 0
615 && (
616 $emailUser["ACTIVE"] === "Y"
617 || $emailUser["EXTERNAL_AUTH_ID"] === "email"
618 )
619 )
620 {
621 if ($emailUser["ACTIVE"] === "N") // email only
622 {
623 $user = new \CUser;
624 $user->update($emailUser["ID"], [
625 'ACTIVE' => 'Y'
626 ]);
627 }
628
629 $userId = $emailUser['ID'];
630 }
631 }
632
633 if (!$userId)
634 {
635 $userFields = [
636 'EMAIL' => $userEmail,
637 'NAME' => $params["NAME"] ?? '',
638 'LAST_NAME' => $params["LAST_NAME"] ?? ''
639 ];
640
641 // create "external" user by email
642 $user = \Bitrix\Mail\User::create($userFields);
643 $errorMessage = false;
644 if (is_object($user) && $user->LAST_ERROR !== '')
645 {
646 $errorMessage = $user->LAST_ERROR;
647 }
648
649 if (!$errorMessage && (int)$user > 0)
650 {
651 $userId = (int)$user;
652 }
653 else
654 {
655 $errorText = $errorMessage;
656 }
657 }
658
659 if (!is_object($user) && (int)$userId > 0)
660 {
661 \Bitrix\Main\UI\Selector\Entities::save([
662 'context' => Util::getUserSelectorContext(),
663 'code' => 'U'.$userId
664 ]);
665 }
666
667 return $userId;
668 }
669
677 public static function getEventDescriptionById(?int $eventId): ?string
678 {
679 if (!$eventId)
680 {
681 return null;
682 }
683
684 $event = EventTable::getList([
685 'filter' => ['=ID' => $eventId,],
686 'select' => ['DESCRIPTION'],
687 'limit' => 1,
688 ])->fetch();
689
690 return is_array($event)
691 ? $event['DESCRIPTION']
692 : null
693 ;
694 }
695
701 public static function getEventById(?int $eventId): ?array
702 {
703 if (!$eventId)
704 {
705 return null;
706 }
707
708 $event = EventTable::query()
709 ->setSelect([
710 'DATE_FROM',
711 'DATE_TO',
712 'DATE_CREATE',
713 'DT_SKIP_TIME',
714 'TZ_FROM',
715 'TZ_TO',
716 'NAME',
717 'DESCRIPTION',
718 'COLOR',
719 'ACCESSIBILITY',
720 'IMPORTANCE',
721 'PRIVATE_EVENT',
722 'RRULE',
723 'LOCATION',
724 'REMIND',
725 'SECTION_ID',
726 'IS_MEETING',
727 'MEETING_HOST',
728 'MEETING',
729 'CAL_TYPE',
730 'OWNER_ID',
731 'VERSION',
732 'PARENT_ID',
733 'TIMESTAMP_X',
734 'LOCATION',
735 'MEETING_STATUS',
736 'DAV_XML_ID',
737 'ID',
738 'ACTIVE',
739 'RELATIONS',
740 'ATTENDEES_CODES',
741 ])
742 ->setFilter(['=ID' => $eventId])
743 ->setLimit(1)
744 ->exec()->fetch()
745 ;
746
747 if ($event)
748 {
749 return $event;
750 }
751
752 return null;
753 }
754
761 public static function getIcalDateTimeShort(string $dateTime = null, string $tz = 'UTC'): DateTime
762 {
763 return new DateTime($dateTime, self::ICAL_DATETIME_FORMAT_SHORT, Util::prepareTimezone($tz));
764 }
765
770 public static function getShortMonthName(?Date $date): string
771 {
772 if ($date === null)
773 {
774 return \date('M');
775 }
776
777 $month = Util::checkRuZone()
778 ? mb_strtoupper(FormatDate('M', $date->getTimestamp()))
779 : mb_strtoupper($date->format('M'))
780 ;
781
782 return is_string($month)
783 ? $month
784 : $date->format('M')
785 ;
786 }
787
793 protected static function isNotEndOfTime($until): bool
794 {
795 return Util::getDateObject($until)->getTimestamp() !== Util::getDateObject(self::END_OF_TIME)->getTimestamp();
796 }
797
803 public static function getDateByParserProperty(?ParserPropertyType $date): ?Date
804 {
805 if ($date !== null)
806 {
807 return $date->getParameterValueByName('tzid') !== null
808 ? self::getIcalDateTime($date->getValue(), $date->getParameterValueByName('tzid'))
809 : self::getIcalDate($date->getValue())
810 ;
811 }
812
813 return null;
814 }
815}
format(string $format=null)
Definition date.php:107
static createInstance(string $link, string $name, int $size)
Definition attach.php:32
static getExternalUserByEmail($params, &$errorText)
Definition helper.php:574
static getAttendee(int $userId, int $eventParentId, $isRsvp=true)
Definition helper.php:450
static getDateObject(string $date=null, $fullDay=true, $tz='UTC')
Definition helper.php:73
static getDateByParserProperty(?ParserPropertyType $date)
Definition helper.php:803
static getDetailLink(int $eventId, int $userId, int $dateCreateTimestamp)
Definition helper.php:335
static getHashForPubEvent(int $eventId, int $userId, int $dateCreateTimestamp)
Definition helper.php:296
static getPubEventLinkWithParameters(int $eventId, int $userId, int $dateCreateTimestamp, string $decision)
Definition helper.php:347
static getTimezoneObject(string $tz=null)
Definition helper.php:178
static getIcalDate(string $date=null)
Definition helper.php:533
static getIcalDateTime(string $dateTime=null, string $tz=null)
Definition helper.php:521
static getAttendeesByEventParentId(int $parentId)
Definition helper.php:494
static getMailAttaches($fields, $userId, $parentId, &$isChangeFiles=false)
Definition helper.php:362
static getUserIdByEmail(array $userInfo)
Definition helper.php:545
static getIndexUsersByIds(?array $idList)
Definition helper.php:252
static getEventDescriptionById(?int $eventId)
Definition helper.php:677
static getPubEventLink(int $eventId, int $userId, int $dateCreateTimestamp)
Definition helper.php:307
static getIcalTemplateRRule(array $rrule=null, array $params=null)
Definition helper.php:92
static getIcalDateTimeShort(string $dateTime=null, string $tz='UTC')
Definition helper.php:761
static getIcalTemplateDate(array $params=null)
Definition helper.php:46
static getUserSelectorContext()
Definition util.php:119
static prepareTimezone(?string $tz=null)
Definition util.php:75
static checkRuZone()
Definition util.php:124
static getDateObject(string $date=null, ?bool $fullDay=true, ?string $tz='UTC')
Definition util.php:102
static getMessage($code, $replace=null, $language=null)
Definition loc.php:29
static getExternalUserTypes()
Definition user.php:305