1C-Bitrix 25.700.0
Загрузка...
Поиск...
Не найдено
helper.php
См. документацию.
1<?php
2
3namespace Bitrix\Calendar\ICal\MailInvitation;
4
5use Bitrix\Calendar\Core\Event\Event;
6use Bitrix\Calendar\ICal\Builder\Attach;
7use Bitrix\Calendar\ICal\Builder\AttachCollection;
8use Bitrix\Calendar\ICal\Builder\Attendee;
9use Bitrix\Calendar\ICal\Builder\AttendeesCollection;
10use Bitrix\Calendar\ICal\Builder\Dictionary;
11use Bitrix\Calendar\ICal\Parser\ParserPropertyType;
12use Bitrix\Calendar\Util;
13use Bitrix\Disk\Uf\FileUserType;
14use Bitrix\Main\Application;
15use Bitrix\Main\ArgumentException;
16use Bitrix\Main\Entity\ReferenceField;
17use Bitrix\Main\Loader;
18use Bitrix\Main\Localization\Loc;
19use Bitrix\Main\ObjectPropertyException;
20use Bitrix\Main\ORM\Entity;
21use Bitrix\Main\ORM\Fields\Relations\Reference;
22use Bitrix\Main\ORM\Query\Join;
23use Bitrix\Main\SystemException;
24use Bitrix\Main\Type\Date;
25use Bitrix\Main\Type\DateTime;
26use COption;
27use DateTimeZone;
28use Bitrix\Calendar\Internals\EventTable;
29use Bitrix\Main\UserTable;
30use \Bitrix\Disk\AttachedObject;
31
32IncludeModuleLangFile($_SERVER['DOCUMENT_ROOT'] . BX_ROOT . '/modules/calendar/classes/general/calendar.php');
33
34class Helper
35{
36 public const ICAL_DATETIME_FORMAT_UTC = 'Ymd\THis\Z';
37 public const ICAL_DATETIME_FORMAT = 'Ymd\THis';
38 public const ICAL_DATETIME_FORMAT_SHORT = 'Ymd\THis';
39 public const ICAL_DATE_FORMAT = 'Ymd';
40 public const END_OF_TIME = "01.01.2038";
41
47 public static function getIcalTemplateDate(array $params = null): string
48 {
49 $from = self::getDateObject($params['DATE_FROM'], false, $params['TZ_FROM']);
50 $to = self::getDateObject($params['DATE_TO'], false, $params['TZ_TO']);
51 if ($from->format('dmY') !== $to->format('dmY'))
52 {
53 $res = $params['FULL_DAY']
54 ? $from->format('d.m.Y') . ' - ' . $to->format('d.m.Y')
55 : $from->format('d.m.Y H:i') . ' - ' . $to->format('d.m.Y H:i');
56 }
57 else
58 {
59 $res = $params['FULL_DAY']
60 ? $from->format('d.m.Y')
61 : $from->format('d.m.Y H:i') . ' - ' . $to->format('H:i');
62 }
63
64 return $res;
65 }
66
74 public static function getDateObject(string $date = null, $fullDay = true, $tz = 'UTC'): Date
75 {
76 $preparedDate = $date;
77 if ($date)
78 {
79 $timestamp = \CCalendar::Timestamp($date, false, !$fullDay);
80 $preparedDate = \CCalendar::Date($timestamp);
81 }
82
83 return $fullDay
84 ? new Date($preparedDate, Date::convertFormatToPhp(FORMAT_DATE))
85 : new DateTime($preparedDate, Date::convertFormatToPhp(FORMAT_DATETIME), Util::prepareTimezone($tz));
86 }
87
93 public static function getIcalTemplateRRule(array $rrule = null, array $params = null): string
94 {
95 $res = '';
96 if ($rrule['BYDAY'] ?? false)
97 {
98 $rrule['BYDAY'] = \CCalendarEvent::sortByDay($rrule['BYDAY']);
99 }
100 switch($rrule['FREQ'] ?? null)
101 {
102 case 'DAILY':
103 $res = (int)$rrule['INTERVAL'] === 1
104 ? Loc::getMessage('EC_RRULE_EVERY_DAY')
105 : Loc::getMessage('EC_RRULE_EVERY_DAY_1', ['#DAY#' => $rrule['INTERVAL']])
106 ;
107 break;
108 case 'WEEKLY':
109 if (!isset($rrule['BYDAY']) || !is_array($rrule['BYDAY']))
110 {
111 $rrule['BYDAY'] = ['MO'];
112 }
113
114 $daysList = implode(', ', array_map(static function($day) {return Loc::getMessage('EC_' . $day);}, $rrule['BYDAY']));
115 $res = (int)$rrule['INTERVAL'] === 1
116 ? Loc::getMessage('EC_RRULE_EVERY_WEEK', ['#DAYS_LIST#' => $daysList])
117 : Loc::getMessage('EC_RRULE_EVERY_WEEK_1', ['#WEEK#' => $rrule['INTERVAL'], '#DAYS_LIST#' => $daysList])
118 ;
119 break;
120 case 'MONTHLY':
121 $res = (int)$rrule['INTERVAL'] === 1
122 ? Loc::getMessage('EC_RRULE_EVERY_MONTH')
123 : Loc::getMessage('EC_RRULE_EVERY_MONTH_1', ['#MONTH#' => $rrule['INTERVAL']])
124 ;
125 break;
126 case 'YEARLY':
127 $fromTs = \CCalendar::Timestamp($params['DATE_FROM']);
128 $res = (int)$rrule['INTERVAL'] === 1
129 ? Loc::getMessage('EC_RRULE_EVERY_YEAR', [
130 '#DAY#' => FormatDate('j', $fromTs),
131 '#MONTH#' => FormatDate('n', $fromTs)
132 ])
133 : Loc::getMessage('EC_RRULE_EVERY_YEAR_1', [
134 '#YEAR#' => $rrule['INTERVAL'],
135 '#DAY#' => FormatDate('j', $fromTs),
136 '#MONTH#' => FormatDate('n', $fromTs)
137 ])
138 ;
139 break;
140 }
141
142 if ($rrule['COUNT'] ?? false)
143 {
144 $res .= ' ' . Loc::getMessage('EC_RRULE_COUNT', ['#COUNT#' => $rrule['COUNT']]);
145 }
146 elseif (isset($rrule['UNTIL']) && $rrule['UNTIL'] && self::isNotEndOfTime($rrule['UNTIL']))
147 {
148 $res .= ' ' . Loc::getMessage('EC_RRULE_UNTIL', ['#UNTIL_DATE#' => $rrule['UNTIL']]);
149 }
150
151 if (!is_string($res))
152 {
153 $res = '';
154 }
155
156 return $res;
157 }
158
162 public static function getUniqId(): string
163 {
164 return uniqid(self::getServerName(), true);
165 }
166
170 public static function getServerName()
171 {
172 return COption::getOptionString('main', 'server_name', Application::getInstance()->getContext()->getServer()->getServerName());
173 }
174
179 public static function getTimezoneObject(string $tz = null): DateTimeZone
180 {
181 return !$tz
182 ? (new \DateTime())->getTimezone()
183 : new DateTimeZone(Util::prepareTimezone($tz)->getName());
184 }
185
194 public static function getEventByUId(?string $uid): ?array
195 {
196 if (is_null($uid))
197 {
198 return null;
199 }
200
201 $event = EventTable::getList([
202 'filter' => [
203 '=DAV_XML_ID' => $uid,
204 '=DELETED' => 'N',
205 ],
206 'limit' => 1,
207 ])->fetch();
208
209 return (!empty($event) && is_array($event))
210 ? $event
211 : null;
212 }
213
221 public static function getUserById(?int $id): ?array
222 {
223 if ($id === null)
224 {
225 return null;
226 }
227
228 $user = UserTable::getList([
229 'filter' => [
230 'ID' => $id,
231 ],
232 'select' => [
233 'ID',
234 'NAME',
235 'LAST_NAME',
236 'EMAIL',
237 ],
238 'limit' => 1,
239 ])->fetch();
240
241 return (!empty($user) && is_array($user))
242 ? $user
243 : null;
244 }
245
253 public static function getIndexUsersByIds(?array $idList): array
254 {
255 $usersDb = UserTable::getList([
256 'filter' => [
257 'ID' => $idList,
258 ],
259 'select' => [
260 'ID',
261 'NAME',
262 'LAST_NAME',
263 'EMAIL',
264 ],
265 ]);
266
267 $collection = [];
268 while ($user = $usersDb->fetch())
269 {
270 $collection[$user['ID']] = $user;
271 }
272
273 return $collection;
274 }
275
286 public static function getMailAttaches($fields, $userId, $parentId, &$isChangeFiles = false): AttachCollection
287 {
288 //TODO: need refactoring
289 global $USER_FIELD_MANAGER;
290 $attachCollection = new AttachCollection();
291 $UF = $USER_FIELD_MANAGER->GetUserFields("CALENDAR_EVENT", $parentId, LANGUAGE_ID);
292 $attachedFilesIds = $UF['UF_WEBDAV_CAL_EVENT']['VALUE'];
293
294 $fields['UF_WEBDAV_CAL_EVENT'] ??= null;
295 if (is_array($fields) && is_array($fields['UF_WEBDAV_CAL_EVENT']) && is_array($attachedFilesIds))
296 {
297 $ufIds = array_unique(array_merge($fields['UF_WEBDAV_CAL_EVENT'], $attachedFilesIds));
298 }
299 elseif(is_array($fields) && is_array($fields['UF_WEBDAV_CAL_EVENT']))
300 {
301 $ufIds = $fields['UF_WEBDAV_CAL_EVENT'];
302 }
303 elseif(is_array($attachedFilesIds))
304 {
305 $ufIds = $attachedFilesIds;
306 }
307 else
308 {
309 return $attachCollection;
310 }
311
312 if (!empty($ufIds) && \Bitrix\Main\Loader::includeModule('disk'))
313 {
314 foreach ($ufIds as $item)
315 {
316 [$type, $realValue] = \Bitrix\Disk\Uf\FileUserType::detectType($item);
317
318 if ($type == FileUserType::TYPE_ALREADY_ATTACHED)
319 {
320 $attachedModel = AttachedObject::loadById($realValue);
321 if(!$attachedModel
322 || (!empty($fields['UF_WEBDAV_CAL_EVENT'])
323 && $item !== ''
324 && !in_array($item, $fields['UF_WEBDAV_CAL_EVENT'])))
325 {
326 $isChangeFiles = true;
327 continue;
328 }
329 $file = $attachedModel->getFile();
330 }
331 elseif ($type == \Bitrix\Disk\Uf\FileUserType::TYPE_NEW_OBJECT)
332 {
333 $isChangeFiles = true;
334 $file = \Bitrix\Disk\File::loadById($realValue, ['STORAGE']);
335 }
336
337 if (!$file)
338 {
339 continue;
340 }
341
342 $externalLink = $file->addExternalLink([
343 'CREATED_BY' => $userId,
344 'TYPE' => \Bitrix\Disk\Internals\ExternalLinkTable::TYPE_MANUAL,
345 ]);
346 if (!$externalLink)
347 {
348 continue;
349 }
350
351 $name = $file->getName();
352 $size = $file->getSize();
353 $link = \Bitrix\Disk\Driver::getInstance()->getUrlManager()->getUrlExternalLink([
354 'hash' => $externalLink->getHash(),
355 'action' => 'downloadFile',
356 ],
357 true
358 );
359
360 $attach = Attach::createInstance($link, $name, $size);
361
362 $attachCollection->add($attach);
363 }
364 }
365
366 return $attachCollection;
367 }
368
374 public static function getAttendee(int $userId, int $eventParentId, $isRsvp = true): ?Attendee
375 {
376 $query = EventTable::query()
377 ->setSelect([
378 'MEETING_STATUS',
379 'USER_NAME' => 'USER.NAME',
380 'USER_LAST_NAME' => 'USER.LAST_NAME',
381 'USER_EMAIL' => 'USER.EMAIL',
382 ])
383 ->registerRuntimeField(
384 'USER',
385 new ReferenceField(
386 'USER',
387 UserTable::getEntity(),
388 Join::on('this.OWNER_ID', 'ref.ID'),
389 ['join_type' => Join::TYPE_INNER]
390 )
391 )
392 ->setFilter(['USER.ID'=>$userId, '=PARENT_ID'=>$eventParentId])
393 ;
394
395 $attendee = $query->fetch();
396
397 if (is_null($attendee))
398 {
399 return null;
400 }
401
402 return Attendee::createInstance(
403 $attendee['USER_EMAIL'],
404 $attendee['USER_NAME'],
405 $attendee['USER_LAST_NAME'],
406 Dictionary::ATTENDEE_STATUS[$attendee['MEETING_STATUS']],
407 Dictionary::ATTENDEE_ROLE['REQ_PARTICIPANT'],
408 Dictionary::ATTENDEE_CUTYPE['individual'],
409 $attendee['USER_EMAIL'],
410 $isRsvp
411 );
412 }
413
418 public static function getAttendeesByEventParentId(int $parentId): AttendeesCollection
419 {
420 $attendeesCollection = AttendeesCollection::createInstance();
421
422 $query = EventTable::query()
423 ->setSelect([
424 'MEETING_STATUS',
425 'USER_NAME' => 'USER.NAME',
426 'USER_LAST_NAME' => 'USER.LAST_NAME',
427 'USER_EMAIL' => 'USER.EMAIL'
428 ])
429 ->where('PARENT_ID', $parentId)
430 ->registerRuntimeField(
431 'USER',
432 new ReferenceField(
433 'USER',
434 UserTable::getEntity(),
435 Join::on('this.OWNER_ID', 'ref.ID'),
436 ['join_type' => Join::TYPE_INNER]
437 )
438 )
439 ->exec()
440 ;
441
442 while ($attendee = $query->fetch())
443 {
444 $attendeesCollection->add(Attendee::createInstance(
445 $attendee['USER_EMAIL'],
446 $attendee['USER_NAME'],
447 $attendee['USER_LAST_NAME'],
448 Dictionary::ATTENDEE_STATUS[$attendee['MEETING_STATUS']],
449 Dictionary::ATTENDEE_ROLE['REQ_PARTICIPANT'],
450 Dictionary::ATTENDEE_CUTYPE['individual'],
451 $attendee['USER_EMAIL']
452 ));
453 }
454
455 return $attendeesCollection;
456 }
457
464 public static function getIcalDateTime(string $dateTime = null, string $tz = null): DateTime
465 {
466 $format = $tz === 'UTC' ? self::ICAL_DATETIME_FORMAT_UTC : self::ICAL_DATETIME_FORMAT;
467
468 return new DateTime($dateTime, $format, Util::prepareTimezone($tz));
469 }
470
476 public static function getIcalDate(string $date = null): Date
477 {
478 return new Date($date, self::ICAL_DATE_FORMAT);
479 }
480
488 public static function getUserIdByEmail(array $userInfo): ?int
489 {
490 $parameters = [
491 'filter' => [
492 'EMAIL' => $userInfo['EMAIL'],
493 ],
494 'select' => ['ID',],
495 'limit' => 1,
496 ];
497
498 $userDd = UserTable::getList($parameters);
499 if ($user = $userDd->fetch())
500 {
501 return (int)$user['ID'];
502 }
503
504 return self::getExternalUserByEmail($userInfo, $errorCollection);
505 }
506
517 public static function getExternalUserByEmail($params, &$errorText): ?int
518 {
519 $userId = null;
520 $user = null;
521
522 if (
523 !is_array($params)
524 || empty($params['EMAIL'])
525 || !check_email($params['EMAIL'])
526 || !Loader::includeModule('mail')
527 )
528 {
529 return $userId;
530 }
531
532 $userEmail = $params['EMAIL'];
533
534 if (
535 empty($userEmail)
536 || !check_email($userEmail)
537 )
538 {
539 return $userId;
540 }
541
542 $res = \CUser::getList(
543 $o = "ID",
544 $b = "ASC",
545 [
546 "=EMAIL" => $userEmail,
547 "!EXTERNAL_AUTH_ID" => \Bitrix\Main\UserTable::getExternalUserTypes(),
548 ],
549 [
550 "FIELDS" => [ "ID", "EXTERNAL_AUTH_ID", "ACTIVE" ]
551 ]
552 );
553
554 while (($emailUser = $res->fetch()) && !$userId)
555 {
556 if (
557 (int)$emailUser["ID"] > 0
558 && (
559 $emailUser["ACTIVE"] === "Y"
560 || $emailUser["EXTERNAL_AUTH_ID"] === "email"
561 )
562 )
563 {
564 if ($emailUser["ACTIVE"] === "N") // email only
565 {
566 $user = new \CUser;
567 $user->update($emailUser["ID"], [
568 'ACTIVE' => 'Y'
569 ]);
570 }
571
572 $userId = $emailUser['ID'];
573 }
574 }
575
576 if (!$userId)
577 {
578 $userFields = [
579 'EMAIL' => $userEmail,
580 'NAME' => $params["NAME"] ?? '',
581 'LAST_NAME' => $params["LAST_NAME"] ?? ''
582 ];
583
584 // create "external" user by email
585 $user = \Bitrix\Mail\User::create($userFields);
586 $errorMessage = false;
587 if (is_object($user) && $user->LAST_ERROR !== '')
588 {
589 $errorMessage = $user->LAST_ERROR;
590 }
591
592 if (!$errorMessage && (int)$user > 0)
593 {
594 $userId = (int)$user;
595 }
596 else
597 {
598 $errorText = $errorMessage;
599 }
600 }
601
602 if (!is_object($user) && (int)$userId > 0)
603 {
605 'context' => Util::getUserSelectorContext(),
606 'code' => 'U'.$userId
607 ]);
608 }
609
610 return $userId;
611 }
612
620 public static function getEventDescriptionById(?int $eventId): ?string
621 {
622 if (!$eventId)
623 {
624 return null;
625 }
626
627 $event = EventTable::getList([
628 'filter' => ['=ID' => $eventId,],
629 'select' => ['DESCRIPTION'],
630 'limit' => 1,
631 ])->fetch();
632
633 return is_array($event)
634 ? $event['DESCRIPTION']
635 : null
636 ;
637 }
638
644 public static function getEventById(?int $eventId): ?array
645 {
646 if (!$eventId)
647 {
648 return null;
649 }
650
651 $event = EventTable::query()
652 ->setSelect([
653 'DATE_FROM',
654 'DATE_TO',
655 'DATE_CREATE',
656 'DT_SKIP_TIME',
657 'TZ_FROM',
658 'TZ_TO',
659 'NAME',
660 'DESCRIPTION',
661 'COLOR',
662 'ACCESSIBILITY',
663 'IMPORTANCE',
664 'PRIVATE_EVENT',
665 'RRULE',
666 'LOCATION',
667 'REMIND',
668 'SECTION_ID',
669 'IS_MEETING',
670 'MEETING_HOST',
671 'MEETING',
672 'CAL_TYPE',
673 'OWNER_ID',
674 'VERSION',
675 'PARENT_ID',
676 'TIMESTAMP_X',
677 'LOCATION',
678 'MEETING_STATUS',
679 'DAV_XML_ID',
680 'ID',
681 'ACTIVE',
682 'RELATIONS',
683 'ATTENDEES_CODES',
684 ])
685 ->setFilter(['=ID' => $eventId])
686 ->setLimit(1)
687 ->exec()->fetch()
688 ;
689
690 if ($event)
691 {
692 return $event;
693 }
694
695 return null;
696 }
697
704 public static function getIcalDateTimeShort(string $dateTime = null, string $tz = 'UTC'): DateTime
705 {
706 return new DateTime($dateTime, self::ICAL_DATETIME_FORMAT_SHORT, Util::prepareTimezone($tz));
707 }
708
713 public static function getShortMonthName(?Date $date): string
714 {
715 if ($date === null)
716 {
717 return \date('M');
718 }
719
720 $month = Util::checkRuZone()
721 ? mb_strtoupper(FormatDate('M', $date->getTimestamp()))
722 : mb_strtoupper($date->format('M'))
723 ;
724
725 return is_string($month)
726 ? $month
727 : $date->format('M')
728 ;
729 }
730
736 protected static function isNotEndOfTime($until): bool
737 {
738 return Util::getDateObject($until)->getTimestamp() !== Util::getDateObject(self::END_OF_TIME)->getTimestamp();
739 }
740
746 public static function getDateByParserProperty(?ParserPropertyType $date): ?Date
747 {
748 if ($date !== null)
749 {
750 return $date->getParameterValueByName('tzid') !== null
751 ? self::getIcalDateTime($date->getValue(), $date->getParameterValueByName('tzid'))
752 : self::getIcalDate($date->getValue())
753 ;
754 }
755
756 return null;
757 }
758}
$type
Определения options.php:106
const BX_ROOT
Определения bx_root.php:3
if(!is_object($USER)||! $USER->IsAuthorized()) $userId
Определения check_mail.php:18
static createInstance(string $link, string $name, int $size)
Определения attach.php:32
static getExternalUserByEmail($params, &$errorText)
Определения helper.php:517
static getAttendee(int $userId, int $eventParentId, $isRsvp=true)
Определения helper.php:374
static getDateObject(string $date=null, $fullDay=true, $tz='UTC')
Определения helper.php:74
static getDateByParserProperty(?ParserPropertyType $date)
Определения helper.php:746
static isNotEndOfTime($until)
Определения helper.php:736
static getEventByUId(?string $uid)
Определения helper.php:194
static getTimezoneObject(string $tz=null)
Определения helper.php:179
static getIcalDate(string $date=null)
Определения helper.php:476
static getIcalDateTime(string $dateTime=null, string $tz=null)
Определения helper.php:464
static getAttendeesByEventParentId(int $parentId)
Определения helper.php:418
static getMailAttaches($fields, $userId, $parentId, &$isChangeFiles=false)
Определения helper.php:286
static getUserIdByEmail(array $userInfo)
Определения helper.php:488
static getShortMonthName(?Date $date)
Определения helper.php:713
static getUserById(?int $id)
Определения helper.php:221
static getIndexUsersByIds(?array $idList)
Определения helper.php:253
static getEventDescriptionById(?int $eventId)
Определения helper.php:620
const ICAL_DATETIME_FORMAT_SHORT
Определения helper.php:38
static getIcalTemplateRRule(array $rrule=null, array $params=null)
Определения helper.php:93
static getEventById(?int $eventId)
Определения helper.php:644
static getIcalDateTimeShort(string $dateTime=null, string $tz='UTC')
Определения helper.php:704
static getIcalTemplateDate(array $params=null)
Определения helper.php:47
static getUserSelectorContext()
Определения util.php:124
static prepareTimezone(?string $tz=null)
Определения util.php:80
static checkRuZone()
Определения util.php:129
static getDateObject(string $date=null, ?bool $fullDay=true, ?string $tz='UTC')
Определения util.php:107
Определения date.php:9
format($format)
Определения date.php:110
getTimestamp()
Определения date.php:218
static save($params=[])
Определения entities.php:1091
static getExternalUserTypes()
Определения user.php:307
</td ></tr ></table ></td ></tr >< tr >< td class="bx-popup-label bx-width30"><?=GetMessage("PAGE_NEW_TAGS")?> array( $site)
Определения file_new.php:804
$res
Определения filter_act.php:7
global $USER_FIELD_MANAGER
Определения attempt.php:6
$query
Определения get_search.php:11
$uid
Определения hot_keys_act.php:8
while($arParentIBlockProperty=$dbParentIBlockProperty->Fetch()) $errorMessage
$_SERVER["DOCUMENT_ROOT"]
Определения cron_frame.php:9
const FORMAT_DATETIME
Определения include.php:64
const FORMAT_DATE
Определения include.php:63
FormatDate($format="", $timestamp=false, $now=false, ?string $languageId=null)
Определения tools.php:871
IncludeModuleLangFile($filepath, $lang=false, $bReturnArray=false)
Определения tools.php:3778
check_email($email, $strict=false, $domainCheck=false)
Определения tools.php:4571
$name
Определения menu_edit.php:35
$user
Определения mysql_to_pgsql.php:33
$event
Определения prolog_after.php:141
if( $daysToExpire >=0 &&$daysToExpire< 60 elseif)( $daysToExpire< 0)
Определения prolog_main_admin.php:393
if($inWords) echo htmlspecialcharsbx(Number2Word_Rus(roundEx($totalVatSum $params['CURRENCY']
Определения template.php:799
$fields
Определения yandex_run.php:501