1C-Bitrix 25.700.0
Загрузка...
Поиск...
Не найдено
calendar_reminder.php
См. документацию.
1<?php
4
6{
7 public const TYPE_DAY_BEFORE = 'daybefore';
8 public const TYPE_SPECIFIC_DATETIME = 'date';
9 public const SIMPLE_TYPE_LIST = ['min', 'hour', 'day'];
10 public const REMINDER_INACCURACY = 30;
11 public const REMINDER_NEXT_DELAY = 120;
12
13 public static function ReminderAgent($eventId = 0, $userId = 0, $viewPath = '', $calendarType = '', $ownerId = 0, $index = 0)
14 {
15 if (empty($userId))
16 {
17 $userId = $ownerId;
18 }
19
20 if ($eventId > 0 && $userId > 0 && \Bitrix\Main\Loader::includeModule("im"))
21 {
22 $event = false;
23 $nowTime = time();
24
25 $events = CCalendarEvent::GetList([
26 'arFilter' => [
27 "ID" => $eventId,
28 "DELETED" => "N",
29 "FROM_LIMIT" => CCalendar::Date($nowTime - 3600, false),
30 "TO_LIMIT" => CCalendar::GetMaxDate(),
31 "ACTIVE_SECTION" => "Y"
32 ],
33 'userId' => $userId,
34 'parseRecursion' => true,
35 'maxInstanceCount' => 3,
36 'preciseLimits' => true,
37 'fetchAttendees' => false,
38 'checkPermissions' => false,
39 'setDefaultLimit' => false
40 ]);
41
42 if ($events && is_array($events[0]))
43 {
44 $event = $events[0];
45 }
46
47 if ($event && $event['MEETING_STATUS'] !== 'N')
48 {
49 $fromTs = CCalendar::Timestamp($event['DATE_FROM'], false, $event['DT_SKIP_TIME'] !== 'Y');
50 if ($event['DT_SKIP_TIME'] !== 'Y')
51 {
52 $fromTs -= $event['~USER_OFFSET_FROM'];
53 }
54
55 if (empty($calendarType))
56 {
57 $calendarType = $event['CAL_TYPE'];
58 }
59
60 $viewPathUri = (new \Bitrix\Main\Web\Uri($viewPath))
61 ->deleteParams(['EVENT_DATE'])
62 ->addParams(['EVENT_DATE' => CCalendar::Date($fromTs, false)])
63 ;
64
65 $notificationFields = self::getNotifyFields([
66 'userId' => $userId,
67 'entryId' => $eventId,
68 'entryName' => $event['NAME'],
69 'location' => Bitrix\Calendar\Rooms\Util::getTextLocation($event['LOCATION']),
70 'calendarType' => $calendarType,
71 'event' => $event,
72 'fromTs' => $fromTs,
73 'dateFrom' => CCalendar::Date($fromTs, $event['DT_SKIP_TIME'] !== 'Y', true, true),
74 'viewPath' => $viewPathUri->getUri(),
75 'index' => $index
76 ]);
77
78 CIMNotify::Add($notificationFields);
79
80 foreach(\Bitrix\Main\EventManager::getInstance()->findEventHandlers("calendar", "OnRemindEvent") as $event)
81 {
83 'eventId' => $eventId,
84 'userId' => $userId,
85 'viewPath' => $viewPathUri->getUri(),
86 'calType' => $calendarType,
87 'ownerId' => $ownerId
88 ]]);
89 }
90
91 if (CCalendarEvent::CheckRecurcion($event))
92 {
94 'id' => $eventId,
95 'arFields' => $event,
96 'userId' => $userId,
97 'path' => $viewPathUri->getUri(),
98 'updateRecursive' => true
99 ]);
100 }
101 }
102
103 CCalendar::SetOffset(false, null);
104 }
105 }
106
107 public static function RemoveAgent($params)
108 {
109 // remove obsolete agents
110 $res = CAgent::getList([], [
111 'NAME' => "CCalendar::ReminderAgent(".$params['eventId'].", ".$params['userId']."%",
112 'MODULE_ID' => 'calendar'
113 ]);
114 while($item = $res->fetch())
115 {
116 CAgent::Delete($item['ID']);
117 }
118 }
119
120 public static function getNotifyFields($params = []): array
121 {
122 $userId = $params['userId'];
123 $entryId = $params['entryId'];
124
125 $notifyFields = [
126 'FROM_USER_ID' => $userId,
127 'TO_USER_ID' => $userId,
128 'NOTIFY_TYPE' => IM_NOTIFY_SYSTEM,
129 'NOTIFY_MODULE' => "calendar",
130 'NOTIFY_EVENT' => "reminder",
131 'NOTIFY_TAG' => "CALENDAR|INVITE|".$entryId."|".$userId."|REMINDER|".$params['fromTs']."|".$params['index'],
132 'NOTIFY_SUB_TAG' => "CALENDAR|INVITE|".$entryId
133 ];
134
135 if ($params['location'])
136 {
137 $notifyFields['MESSAGE'] = fn (?string $languageId = null) =>
138 Loc::getMessage(
139 'EC_EVENT_REMINDER_1',
140 [
141 '#EVENT_NAME#' => $params['entryName'],
142 '#DATE_FROM#' => $params['dateFrom'],
143 '#URL_VIEW#' => $params['viewPath']
144 ],
145 $languageId
146 )
147 . "\n\n"
148 . Loc::getMessage(
149 'EC_EVENT_REMINDER_LOCATION',
150 ['#LOCATION#' => $params['location']],
151 $languageId
152 );
153 }
154 else
155 {
156 $notifyFields['MESSAGE'] = fn (?string $languageId = null) => Loc::getMessage(
157 'EC_EVENT_REMINDER_1',
158 [
159 '#EVENT_NAME#' => $params['entryName'],
160 '#DATE_FROM#' => $params['dateFrom'],
161 '#URL_VIEW#' => $params['viewPath']
162 ],
163 $languageId
164 );
165 }
166
167 $dateFromFormatted = fn (?string $languageId = null) => CCalendar::GetFromToHtml(
168 $params['fromTs'],
169 $params['fromTs'] + $params['event']['DT_LENGTH'],
170 $params['event']['DT_SKIP_TIME'] === 'Y',
171 $params['event']['DT_LENGTH'],
172 $languageId
173 );
174
175 $notifyFields["PUSH_MESSAGE"] = fn (?string $languageId = null) => self::getPushMessage(
176 $params['entryName'],
177 $dateFromFormatted($languageId),
178 $languageId
179 );
180
181 return $notifyFields;
182 }
183
184 private static function getPushMessage($entryName, $dateFromFormatted, $languageId = null): string
185 {
186 $result = Loc::getMessage(
187 'EC_EVENT_REMINDER_PUSH',
188 [
189 '#EVENT_NAME#' => $entryName,
190 '#DATE_FROM#' => $dateFromFormatted
191 ],
192 $languageId
193 );
194 $result = str_replace('&ndash;', '-', $result);
195
196 return mb_substr($result, 0, \CCalendarNotify::PUSH_MESSAGE_MAX_LENGTH);
197 }
198
199 public static function AddAgent($remindTime, $params): void
200 {
201 global $DB;
202 if (!empty($remindTime) && $DB->IsDate($remindTime, false, LANG, "FULL"))
203 {
204 $tzEnabled = CTimeZone::Enabled();
205 if ($tzEnabled)
206 {
207 CTimeZone::Disable();
208 }
209 $indexParam = isset($params['index']) ? ', '.$params['index'] : '';
210
211 CAgent::AddAgent(
212 "CCalendar::ReminderAgent(".(int)$params['eventId'].", "
213 .(int)$params['userId'].", '"
214 .addslashes($params['viewPath'])."', '"
215 .addslashes($params['calendarType'])."', "
216 .(int)$params['ownerId'].$indexParam.");",
217 "calendar",
218 "Y",
219 0,
220 "",
221 "Y",
222 $remindTime,
223 100,
224 false,
225 false
226 );
227
228 if ($tzEnabled)
229 {
230 CTimeZone::Enable();
231 }
232 }
233 }
234
235 public static function updateReminders($params = []): void
236 {
237 $eventId = (int)$params['id'];
238 $entryFields = $params['arFields'];
239 $reminders = $params['reminders'] ?? null;
240 $userId = (int)$params['userId'];
241 $ownerId = $entryFields['OWNER_ID'] ?? $entryFields['CREATED_BY'] ?? null;
242
243 if (!$reminders)
244 {
245 $reminders = self::prepareReminder($entryFields['REMIND']);
246 }
247
248 $path = CCalendar::GetPathForCalendarEx($ownerId);
249
250 $viewPath = (new \Bitrix\Main\Web\Uri($path))
251 ->deleteParams(["action", "sessid", "bx_event_calendar_request", "EVENT_ID", "EVENT_DATE"])
252 ->addParams(['EVENT_ID' => $eventId])
253 ;
254
255 $agentParams = [
256 'eventId' => $eventId,
257 'userId' => $ownerId,
258 'viewPath' => $viewPath->getUri(),
259 'calendarType' => $entryFields["CAL_TYPE"] ?? null,
260 'ownerId' => $entryFields["OWNER_ID"] ?? null
261 ];
262
263 // 1. clean reminders
264 self::RemoveAgent($agentParams);
265
266 // Prevent duplication of reminders for non-user's calendar context (mantis:0128287)
267 if ($entryFields['CAL_TYPE'] === 'user')
268 {
269 // 2. Set new reminders
270 if (CCalendarEvent::CheckRecurcion($entryFields))
271 {
272 $entryList = CCalendarEvent::GetList(
273 [
274 'arFilter' => [
275 "ID" => $eventId,
276 "DELETED" => "N",
277 "FROM_LIMIT" => CCalendar::Date(time() - 3600, false),
278 "TO_LIMIT" => CCalendar::GetMaxDate()
279 ],
280 'arSelect' => CCalendarEvent::$defaultSelectEvent,
281 'userId' => $userId,
282 'parseRecursion' => true,
283 'maxInstanceCount' => 4,
284 'preciseLimits' => true,
285 'fetchAttendees' => false,
286 'checkPermissions' => false,
287 'setDefaultLimit' => false
288 ]
289 );
290
291 if (is_array($entryList))
292 {
293 $index = 0;
294 foreach ($entryList as $entry)
295 {
296 $eventTimestamp = CCalendar::Timestamp($entry['DATE_FROM'], false, true);
297 $eventTimestamp = $eventTimestamp - CCalendar::GetTimezoneOffset($entry["TZ_FROM"], $eventTimestamp) + (int)date("Z", $eventTimestamp);
298
299 // List of added timestamps of reminders to avoid duplication
300 $addedIndex = [];
301 foreach ($reminders as $reminder)
302 {
303 $reminderTimestamp = self::getReminderTimestamp(
304 $eventTimestamp,
305 $reminder,
306 $entryFields['TZ_FROM'] ?? null
307 );
308
309 $limitTime = !empty($params['updateRecursive'])
310 ? time() + self::REMINDER_NEXT_DELAY
311 : time() - self::REMINDER_INACCURACY;
312
313 if (
314 !is_null($reminderTimestamp)
315 && !in_array($reminderTimestamp, $addedIndex)
316 && $reminderTimestamp >= $limitTime
317 )
318 {
319 $agentParams['index'] = $index++;
320 if ($reminder['type'] === self::TYPE_SPECIFIC_DATETIME)
321 {
322 unset($agentParams['index']);
323 }
324 self::AddAgent(\CCalendar::Date($reminderTimestamp), $agentParams);
325 $addedIndex[] = $reminderTimestamp;
326 }
327 }
328 }
329 }
330 }
331 else
332 {
333 // Start of the event in server timezone
334 $eventTimestamp = $entryFields['DATE_FROM_TS_UTC'] + (int)date("Z", $entryFields['DATE_FROM_TS_UTC']);
335 $index = 0;
336 // List of added timestamps of reminders to avoid duplication
337 $addedIndex = [];
338 foreach ($reminders as $reminder)
339 {
340 $reminderTimestamp = self::getReminderTimestamp(
341 $eventTimestamp,
342 $reminder,
343 $entryFields['TZ_FROM'] ?? null
344 );
345
346 if (
347 !is_null($reminderTimestamp)
348 && !in_array($reminderTimestamp, $addedIndex)
349 && $reminderTimestamp >= time() + self::REMINDER_INACCURACY
350 )
351 {
352 $agentParams['index'] = $index++;
353 self::AddAgent(\CCalendar::Date($reminderTimestamp), $agentParams);
354 $addedIndex[] = $reminderTimestamp;
355 }
356 }
357 }
358 }
359 }
360
361 public static function sortReminder($a, $b): int
362 {
364 }
365
366 public static function getReminderDelta($reminder): int
367 {
368 $delta = 0;
369 if (is_array($reminder) && in_array($reminder['type'], self::SIMPLE_TYPE_LIST, true))
370 {
371 $delta = (int)$reminder['count'] * 60;
372 if ($reminder['type'] === 'hour')
373 {
374 $delta *= 60; //Hour
375 }
376 elseif ($reminder['type'] === 'day')
377 {
378 $delta *= 60 * 24; //Day
379 }
380 }
381
382 return $delta;
383 }
384
385 public static function getReminderTimestamp($eventTimestamp, $reminder, $timezoneName = null)
386 {
387 $reminderTimestamp = null;
388
389 if (is_array($reminder) && isset($reminder['type']))
390 {
391 $type = $reminder['type'];
392
393 if (in_array($type, self::SIMPLE_TYPE_LIST, true))
394 {
395 $delta = (int)$reminder['count'] * 60;
396 if ($reminder['type'] === 'hour')
397 {
398 $delta *= 60; //Hour
399 }
400 elseif ($reminder['type'] === 'day')
401 {
402 $delta *= 60 * 24; //Day
403 }
404
405 $reminderTimestamp = $eventTimestamp - $delta;
406 }
407 elseif($type === self::TYPE_DAY_BEFORE)
408 {
409 $daysBefore = (int)$reminder['before'];
410 $hour = floor((int)$reminder['time'] / 60);
411 $min = (int)($reminder['time'] - $hour * 60);
412
413 $reminderTimestamp = mktime($hour, $min, 0, date("m", $eventTimestamp), date("d", $eventTimestamp) - $daysBefore, date("Y", $eventTimestamp));
414
415 if ($timezoneName)
416 {
417 $timezoneServerOffset = \CCalendar::GetTimezoneOffset($timezoneName, $eventTimestamp) - date("Z", $eventTimestamp);
418 $reminderTimestamp -= $timezoneServerOffset;
419 }
420 }
421 elseif($type === self::TYPE_SPECIFIC_DATETIME)
422 {
423 $reminderTimestamp = \CCalendar::Timestamp($reminder['value'], false, true);
424 $reminderTimestamp = $reminderTimestamp - \CCalendar::GetTimezoneOffset($timezoneName, $reminderTimestamp) + (int)date("Z", $reminderTimestamp);
425 }
426 }
427
428 return $reminderTimestamp;
429 }
430
431 public static function prepareReminder($reminder = []): array
432 {
433 $reminderList = [];
434 if (is_array($reminder))
435 {
436 foreach ($reminder as $remindValue)
437 {
438 if (is_array($remindValue))
439 {
440 if (isset($remindValue['type']) && in_array($remindValue['type'], self::SIMPLE_TYPE_LIST, true))
441 {
442 $reminderList[] = [
443 'type' => $remindValue['type'],
444 'count' => (int)$remindValue['count']
445 ];
446 }
447 elseif ($remindValue['type'] === self::TYPE_DAY_BEFORE)
448 {
449 $reminderList[] = [
450 'type' => $remindValue['type'],
451 'before' => (int)$remindValue['before'],
452 'time' => (int)$remindValue['time']
453 ];
454 }
455 elseif ($remindValue['type'] === self::TYPE_SPECIFIC_DATETIME)
456 {
457 $reminderList[] = [
458 'type' => $remindValue['type'],
459 'value' => \CCalendar::Date(\CCalendar::Timestamp($remindValue['value']))
460 ];
461 }
462 }
463 else
464 {
465 $explodedValue = explode('|', $remindValue);
466 if (count($explodedValue) > 1)
467 {
468 if ($explodedValue[0] === self::TYPE_DAY_BEFORE)
469 {
470 $reminderList[] = [
471 'type' => self::TYPE_DAY_BEFORE,
472 'before' => (int)$explodedValue[1],
473 'time' => (int)$explodedValue[2]
474 ];
475 }
476 elseif($explodedValue[0] === self::TYPE_SPECIFIC_DATETIME)
477 {
478 $reminderList[] = [
479 'type' => self::TYPE_SPECIFIC_DATETIME,
480 'value' => \CCalendar::Date(\CCalendar::Timestamp($explodedValue[1]))
481 ];
482 }
483 }
484 else
485 {
486 $reminderList[] = [
487 'type' => 'min',
488 'count' => (int)$remindValue
489 ];
490 }
491 }
492 }
493 }
494
495 usort($reminderList, ['CCalendarReminder', 'sortReminder']);
496
497 return $reminderList;
498 }
499
500 public static function GetTextReminders($valueList = array())
501 {
502 if (is_array($valueList))
503 {
504 foreach($valueList as $i => $value)
505 {
506 if($value['type'] === 'min')
507 {
508 $value['text'] = Loc::getMessage('EC_REMIND1_VIEW_'.$value['count']);
509 if(!$value['text'])
510 {
511 $value['text'] = Loc::getMessage(
512 'EC_REMIND1_VIEW_MIN_COUNT',
513 ['#COUNT#' => (int)$value['count']]
514 );
515 }
516 }
517 elseif($value['type'] === 'hour')
518 {
519 $value['text'] = Loc::getMessage(
520 'EC_REMIND1_VIEW_HOUR_COUNT',
521 ['#COUNT#' => (int)$value['count']]
522 );
523 }
524 elseif($value['type'] === 'day')
525 {
526 $value['text'] = Loc::getMessage(
527 'EC_REMIND1_VIEW_DAY_COUNT',
528 ['#COUNT#' => (int)$value['count']]
529 );
530 }
531 $valueList[$i] = $value;
532 }
533 }
534 return $valueList;
535 }
536}
$path
Определения access_edit.php:21
$type
Определения options.php:106
if(!is_object($USER)||! $USER->IsAuthorized()) $userId
Определения check_mail.php:18
static getInstance()
Определения servicelocator.php:33
static includeModule($moduleName)
Определения loader.php:67
static sortReminder($a, $b)
Определения calendar_reminder.php:361
const TYPE_DAY_BEFORE
Определения calendar_reminder.php:7
static getReminderTimestamp($eventTimestamp, $reminder, $timezoneName=null)
Определения calendar_reminder.php:385
const TYPE_SPECIFIC_DATETIME
Определения calendar_reminder.php:8
static getReminderDelta($reminder)
Определения calendar_reminder.php:366
static prepareReminder($reminder=[])
Определения calendar_reminder.php:431
const SIMPLE_TYPE_LIST
Определения calendar_reminder.php:9
static ReminderAgent($eventId=0, $userId=0, $viewPath='', $calendarType='', $ownerId=0, $index=0)
Определения calendar_reminder.php:13
static GetTextReminders($valueList=array())
Определения calendar_reminder.php:500
const REMINDER_NEXT_DELAY
Определения calendar_reminder.php:11
static AddAgent($remindTime, $params)
Определения calendar_reminder.php:199
static updateReminders($params=[])
Определения calendar_reminder.php:235
static getNotifyFields($params=[])
Определения calendar_reminder.php:120
const REMINDER_INACCURACY
Определения calendar_reminder.php:10
static RemoveAgent($params)
Определения calendar_reminder.php:107
</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
$result
Определения get_property_values.php:14
const IM_NOTIFY_SYSTEM
Определения include.php:38
global $DB
Определения cron_frame.php:29
ExecuteModuleEventEx($arEvent, $arParams=[])
Определения tools.php:5214
$event
Определения prolog_after.php:141
$delta
Определения prolog_main_admin.php:363
if( $daysToExpire >=0 &&$daysToExpire< 60 elseif)( $daysToExpire< 0)
Определения prolog_main_admin.php:393
$i
Определения factura.php:643
</p ></td >< td valign=top style='border-top:none;border-left:none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;padding:0cm 2.0pt 0cm 2.0pt;height:9.0pt'>< p class=Normal align=center style='margin:0cm;margin-bottom:.0001pt;text-align:center;line-height:normal'>< a name=ТекстовоеПоле54 ></a ><?=($taxRate > count( $arTaxList) > 0) ? $taxRate."%"
Определения waybill.php:936
if($inWords) echo htmlspecialcharsbx(Number2Word_Rus(roundEx($totalVatSum $params['CURRENCY']
Определения template.php:799
else $a
Определения template.php:137
$reminder
Определения options.php:2415