1C-Bitrix 25.700.0
Загрузка...
Поиск...
Не найдено
calendarfilter.php
См. документацию.
1<?php
2
4
9use Bitrix\Main\Entity\ReferenceField;
13
15{
16 public const PRESET_INVITED = 'filter_calendar_meeting_status_q';
17 private const PRESET_HOST = 'filter_calendar_host';
18 private const PRESET_ATTENDEE = 'filter_calendar_attendee';
19 private const PRESET_DECLINED = 'filter_calendar_declined';
20
21 protected static $filterId = '';
22
23 protected static array $filters;
24
29 protected static function getAvailableFields(): array
30 {
31 return [
32 'CREATED_BY',
33 'ATTENDEES',
34 'IS_MEETING',
35 'IS_RECURSIVE',
36 'MEETING_STATUS',
37 'MEETING_HOST',
38 'DATE_FROM',
39 'DATE_TO',
40 'SECTION_ID',
41 'FROM_LIMIT',
42 'TO_LIMIT',
43 ];
44 }
45
53 public static function getFilterId($type, $ownerId, $userId): string
54 {
55 static::$filterId = 'calendar-filter';
56 if ($type === 'user' && (int)$ownerId === (int)$userId)
57 {
58 static::$filterId = 'calendar-filter-personal';
59 }
60 else if (
61 $type === 'company_calendar'
62 || $type === 'calendar_company'
63 || $type === 'company'
64 )
65 {
66 static::$filterId = 'calendar-filter-company';
67 }
68 else if ($type === 'group')
69 {
70 static::$filterId = 'calendar-filter-group';
71 }
72
73 return static::$filterId;
74 }
75
79 public static function setFilterId($filterId)
80 {
81 static::$filterId = $filterId;
82 }
83
89 public static function getPresets($type): array
90 {
91 $presets = [];
92 if ($type === Dictionary::CALENDAR_TYPE['user'] || $type === Dictionary::CALENDAR_TYPE['group'])
93 {
94 $presets[self::PRESET_INVITED] = [
95 'id' => self::PRESET_INVITED,
96 'name' => Loc::getMessage('CALENDAR_PRESET_MEETING_STATUS_Q'),
97 'default' => false,
98 'fields' => [
99 'IS_MEETING' => 'Y',
100 'MEETING_STATUS' => 'Q',
101 ]
102 ];
103 }
104
105 $presets[self::PRESET_HOST] = [
106 'id' => self::PRESET_HOST,
107 'name' => Loc::getMessage('CALENDAR_PRESET_I_AM_HOST'),
108 'default' => false,
109 'fields' => [
110 'MEETING_STATUS' => 'H',
111 ]
112 ];
113
114 $presets[self::PRESET_ATTENDEE] = [
115 'id' => self::PRESET_ATTENDEE,
116 'name' => Loc::getMessage('CALENDAR_PRESET_I_AM_ATTENDEE'),
117 'default' => false,
118 'fields' => [
119 'IS_MEETING' => 'Y',
120 'MEETING_STATUS' => 'Y',
121 ]
122 ];
123
124 $presets[self::PRESET_DECLINED] = [
125 'id' => self::PRESET_DECLINED,
126 'name' => Loc::getMessage('CALENDAR_PRESET_I_DECLINED'),
127 'default' => false,
128 'fields' => [
129 'IS_MEETING' => 'Y',
130 'MEETING_STATUS' => 'N',
131 ]
132 ];
133
134 return $presets;
135 }
136
142 public static function resolveFilterFields(string $filterId): array
143 {
144 $filterOptions = new \Bitrix\Main\UI\Filter\Options($filterId);
145 $fields = $filterOptions->getFilter();
146
147 $preset = $fields['PRESET_ID'] ?? null;
148 $meetingStatus = $fields['MEETING_STATUS'] ?? null;
149 if ($meetingStatus === 'Q')
150 {
151 $preset = self::PRESET_INVITED;
152 }
153 if ($meetingStatus === 'Y')
154 {
155 $preset = self::PRESET_ATTENDEE;
156 }
157 if ($meetingStatus === 'N')
158 {
159 $preset = self::PRESET_DECLINED;
160 }
161
162 $result = [
163 'search' => $filterOptions->getSearchString(),
164 'presetId' => $preset,
165 'fields' => []
166 ];
167 $connection = Application::getConnection();
168 $sqlHelper = $connection->getSqlHelper();
169
170 $fieldNames = self::getAvailableFields();
171 foreach ($fields as $key => $value)
172 {
173 if ($key === 'DATE_from')
174 {
175 $result['fields']['DATE_FROM'] = $value;
176 }
177 else if ($key === 'DATE_to')
178 {
179 $result['fields']['DATE_TO'] = $value;
180 }
181 else if ($key === 'ATTENDEES' || $key === 'CREATED_BY' || $key === 'SECTION_ID')
182 {
183 $valueList = [];
184 foreach ($value as $code)
185 {
186 $valueList[] = (int)$code;
187 }
188 $result['fields'][$key] = $valueList;
189 }
190 else if ($key === 'MEETING_STATUS')
191 {
192 $result['fields']['MEETING_STATUS'] = $sqlHelper->forSql($value);
193 }
194 else if (in_array($key, $fieldNames, true))
195 {
196 $result['fields'][$key] = $value;
197 }
198 }
199
200 return $result;
201 }
202
206 public static function getFilters(): array
207 {
208 if (empty(static::$filters))
209 {
210 static::$filters['CREATED_BY'] = [
211 'id' => 'CREATED_BY',
212 'name' => Loc::getMessage('CALENDAR_FILTER_CREATED_BY'),
213 'type' => 'entity_selector',
214 'partial' => true,
215 'params' => [
216 'multiple' => 'Y',
217 'dialogOptions' => [
218 'height' => 240,
219 'context' => 'filter',
220 'entities' => [
221 [
222 'id' => 'user',
223 'options' => [
224 'inviteEmployeeLink' => false
225 ],
226 ]
227 ]
228 ],
229 ],
230 ];
231
232 static::$filters['ATTENDEES'] = [
233 'id' => 'ATTENDEES',
234 'name' => Loc::getMessage('CALENDAR_FILTER_ATTENDEES'),
235 'type' => 'entity_selector',
236 'partial' => true,
237 'params' => [
238 'multiple' => 'Y',
239 'dialogOptions' => [
240 'height' => 270,
241 'context' => 'filter',
242 'entities' => [
243 [
244 'id' => 'user',
245 'options' => [
246 'inviteEmployeeLink' => false
247 ],
248 ],
249 ]
250 ],
251 ],
252 ];
253
254 static::$filters['MEETING_STATUS'] = [
255 'id' => 'MEETING_STATUS',
256 'name' => Loc::getMessage('CALENDAR_FILTER_MEETING_STATUS_ME'),
257 'type' => 'list',
258 'params' => [
259 'multiple' => 'N'
260 ],
261 'items' => [
262 'H' => Loc::getMessage('CALENDAR_FILTER_MEETING_STATUS_H'),
263 'Q' => Loc::getMessage('CALENDAR_FILTER_MEETING_STATUS_Q'),
264 'Y' => Loc::getMessage('CALENDAR_FILTER_MEETING_STATUS_Y'),
265 'N' => Loc::getMessage('CALENDAR_FILTER_MEETING_STATUS_N'),
266 ]
267 ];
268
269 static::$filters['DATE'] = [
270 'id' => 'DATE',
271 'name' => Loc::getMessage('CALENDAR_FILTER_DATE'),
272 'type' => 'date',
273 'default' => true,
274 ];
275 }
276
277 return static::$filters;
278 }
279
280 public static function getSectionsForFilter(string $type, ?string $preset, ?int $ownerId, ?int $userId): array
281 {
282 $result = [];
283
284 if ($type === 'group' && $preset === self::PRESET_INVITED)
285 {
286 $sectionList = \CCalendar::getSectionList([
287 'CAL_TYPE' => Dictionary::CALENDAR_TYPE['user'],
288 'OWNER_ID' => array_unique([(int)$userId, 0]),
289 'checkPermissions' => true,
290 'getPermissions' => true,
291 ]);
292 }
293 else
294 {
295 $sectionList = \CCalendar::getSectionList([
296 'CAL_TYPE' => $type === 'user' ? ['user', 'open_event'] : $type,
297 'OWNER_ID' => array_unique([(int)$ownerId, 0]),
298 'checkPermissions' => true,
299 'getPermissions' => true,
300 ]);
301 }
302
303 $isPersonalCalendarContext = ($type === 'user' && $userId === $ownerId);
304
305 $hiddenSections = [];
306 if ($preset !== self::PRESET_INVITED)
307 {
308 $hiddenSections = UserSettings::getHiddenSections(
309 $userId,
310 [
311 'type' => $type,
312 'ownerId' => $ownerId,
313 'isPersonalCalendarContext' => $isPersonalCalendarContext,
314 ]
315 );
316 $hiddenSections = array_map(static function($sectionId) {
317 return (int)$sectionId;
318 }, $hiddenSections);
319 }
320
321 foreach ($sectionList as $section)
322 {
323 if (in_array((int)$section['ID'], $hiddenSections, true))
324 {
325 continue;
326 }
327
328 $result[] = (int)$section['ID'];
329 }
330
331 return $result;
332 }
333
342 public static function getFilterData(array $params): array
343 {
344 $connection = Application::getConnection();
345 $sqlHelper = $connection->getSqlHelper();
346 $userId = (int)$params['userId'];
347 $ownerId = (int)$params['ownerId'];
348 $type = $sqlHelper->forSql($params['type']);
349
351 self::getFilterId($type, $ownerId, $userId)
352 );
353 $fields['fields']['SECTION_ID'] = self::getSectionsForFilter(
354 $params['type'],
355 $fields['presetId'],
356 $params['ownerId'],
357 $params['userId'],
358 );
359
360 if (
361 $type === 'company_calendar'
362 || $type === 'calendar_company'
363 || $type === 'company'
364 || $type === 'group'
365 )
366 {
368 }
369
370 return self::getFilterUserData($type, $userId, $ownerId, $fields);
371 }
372
384 public static function getFilterUserData(string $type, int $userId, int $ownerId, $fields): array
385 {
386 $counters = false;
387 $entries = [];
388 $filter = [
389 'OWNER_ID' => $ownerId,
390 'CAL_TYPE' => $type === 'user' ? ['user', 'open_event'] : $type,
391 'ACTIVE_SECTION' => 'Y',
392 ];
393
394 if (isset($fields['fields']['IS_MEETING']))
395 {
396 $filter['IS_MEETING'] = $fields['fields']['IS_MEETING'] === 'Y';
397 }
398
399 if (isset($fields['fields']['MEETING_STATUS']))
400 {
401 $filter['MEETING_STATUS'] = $fields['fields']['MEETING_STATUS'];
402 if ($filter['MEETING_STATUS'] === 'H')
403 {
404 unset($filter['MEETING_STATUS']);
405 $filter['MEETING_HOST'] = $userId;
406 }
407 else
408 {
409 $filter['IS_MEETING'] = true;
410 }
411
412 if ($fields['presetId'] === self::PRESET_INVITED)
413 {
414 $filter['FROM_LIMIT'] = \CCalendar::Date(time(), false);
415 $filter['TO_LIMIT'] = \CCalendar::Date(time() + \CCalendar::DAY_LENGTH * 90, false);
416
417 \CCalendar::UpdateCounter(
418 users: [$userId],
419 groupIds: $type === Dictionary::CALENDAR_TYPE['group'] ? [$ownerId] : [],
420 );
421
422 $counters = CountersManager::getValues((int)$filter['OWNER_ID']);
423 }
424 }
425
426 if (isset($fields['fields']['CREATED_BY']))
427 {
428 unset($filter['OWNER_ID'], $filter['CAL_TYPE']);
429 $filter['MEETING_HOST'] = $fields['fields']['CREATED_BY'];
430 // mantis: 93743
431 $filter['OWNER_ID'] = $userId;
432 }
433
434 if (!empty($fields['fields']['SECTION_ID']))
435 {
436 $filter['SECTION'] = $fields['fields']['SECTION_ID'];
437 }
438 else
439 {
440 return [
441 'result' => true,
442 'entries' => $entries,
443 'counters' => $counters
444 ];
445 }
446
447 if (isset($fields['fields']['ATTENDEES']))
448 {
449 $query = EventTable::query()
450 ->setSelect(['ID'])
451 ->registerRuntimeField(
452 'EVENT_SECOND',
453 new ReferenceField(
454 'EVENT_SECOND',
455 EventTable::getEntity(),
456 Join::on('ref.PARENT_ID', 'this.PARENT_ID'),
457 ['join_type' => Join::TYPE_LEFT]
458 )
459 )
460 ->where('DELETED', 'N')
461 ->where('EVENT_SECOND.DELETED', 'N')
462 ->where('CAL_TYPE', $type)
463 ->where('OWNER_ID', $userId)
464 ->whereIn('EVENT_SECOND.OWNER_ID', $fields['fields']['ATTENDEES'])
465 ->exec()
466 ;
467
468 while ($event = $query->fetch())
469 {
470 $filter['ID'][] = (int)$event['ID'];
471 }
472
473 if (!empty($filter['ID']))
474 {
475 $filter['ID'] = array_unique($filter['ID']);
476 }
477 else
478 {
479 $filter['ID'] = [0];
480 }
481
482 $filter['IS_MEETING'] = true;
483 }
484
485 if ($type === Dictionary::CALENDAR_TYPE['group'] && $fields['presetId'] === self::PRESET_INVITED)
486 {
487 $filter['OWNER_ID'] = $userId;
488 $filter['CAL_TYPE'] = ['user', 'open_event'];
489
490 $query = EventTable::query()
491 ->setSelect(['ID'])
492 ->registerRuntimeField(
493 'EVENT_SECOND',
494 new ReferenceField(
495 'EVENT_SECOND',
496 EventTable::getEntity(),
497 Join::on('ref.ID', 'this.PARENT_ID'),
498 ['join_type' => Join::TYPE_LEFT]
499 )
500 )
501 ->where('DELETED', 'N')
502 ->where('EVENT_SECOND.DELETED', 'N')
503 ->where('CAL_TYPE', Dictionary::CALENDAR_TYPE['user'])
504 ->where('EVENT_SECOND.CAL_TYPE', $type)
505 ->where('OWNER_ID', $userId)
506 ->where('EVENT_SECOND.OWNER_ID', $ownerId)
507 ->where('MEETING_STATUS', Dictionary::MEETING_STATUS['Question'])
508 ->exec()
509 ;
510
511 while ($event = $query->fetch())
512 {
513 $filter['ID'][] = (int)$event['ID'];
514 }
515
516 if (!empty($filter['ID']))
517 {
518 $filter['ID'] = array_unique($filter['ID']);
519 }
520 else
521 {
522 $filter['ID'] = [0];
523 }
524 }
525
526 [$filter, $parseRecursion] = self::filterByDate($fields, $filter);
527
528 if (isset($fields['search']) && $fields['search'])
529 {
530 $filter[(\CCalendarEvent::isFullTextIndexEnabled() ? '*' : '*%').'SEARCHABLE_CONTENT'] = \CCalendarEvent::prepareToken(Emoji::encode($fields['search']));
531 }
532
533 $entries = \CCalendarEvent::GetList(
534 [
535 'arFilter' => $filter,
536 'fetchAttendees' => true,
537 'parseRecursion' => $parseRecursion,
538 'maxInstanceCount' => 50,
539 'preciseLimits' => $parseRecursion,
540 'userId' => $userId,
541 'fetchMeetings' => true,
542 'fetchSection' => true,
543 'setDefaultLimit' => false
544 ]
545 );
546 if ($fields['presetId'] !== self::PRESET_DECLINED)
547 {
548 $entries = self::filterByShowDeclined($entries);
549 }
550
551 return [
552 'result' => true,
553 'entries' => $entries,
554 'counters' => $counters
555 ];
556 }
557
569 public static function getFilterCompanyData(string $type, int $userId, int $ownerId, $fields): array
570 {
571 $entries = [];
572
573 if ($type === Dictionary::CALENDAR_TYPE['group'] && $fields['presetId'] === self::PRESET_INVITED)
574 {
575 return self::getFilterUserData($type, $userId, $ownerId, $fields);
576 }
577
578 $filter = [
579 'CAL_TYPE' => $type,
580 'ACTIVE_SECTION' => 'Y',
581 ];
582
583 $query = EventTable::query()
584 ->setSelect(['PARENT_ID'])
585 ->registerRuntimeField(
586 'EVENT_SECOND',
587 new ReferenceField(
588 'EVENT_SECOND',
589 EventTable::getEntity(),
590 Join::on('ref.PARENT_ID', 'this.ID'),
591 ['join_type' => Join::TYPE_LEFT]
592 )
593 )
594 ->where('CAL_TYPE', $type)
595 ->where('DELETED', 'N')
596 ->where('EVENT_SECOND.DELETED', 'N')
597 ;
598
599 if (isset($fields['fields']['IS_MEETING']) && $fields['fields']['IS_MEETING'])
600 {
601 $filter['IS_MEETING'] = $fields['fields']['IS_MEETING'] === 'Y';
602 }
603
604 if (isset($fields['fields']['MEETING_STATUS']) && $fields['fields']['MEETING_STATUS'])
605 {
606 $query->where('EVENT_SECOND.OWNER_ID', $userId);
607 if (
608 $fields['fields']['MEETING_STATUS'] === 'H'
609 && !isset($fields['fields']['CREATED_BY'])
610 )
611 {
612 unset($filter['IS_MEETING']);
613 $query->where('EVENT_SECOND.MEETING_HOST', $userId);
614 }
615 else
616 {
617 $query->where('EVENT_SECOND.MEETING_STATUS', $fields['fields']['MEETING_STATUS']);
618 $filter['IS_MEETING'] = true;
619 }
620 }
621
622 if (isset($fields['fields']['CREATED_BY']) && is_array($fields['fields']['CREATED_BY']))
623 {
624 $query->whereIn('EVENT_SECOND.MEETING_HOST', $fields['fields']['CREATED_BY']);
625 }
626
627 if (isset($fields['fields']['SECTION_ID']) && is_array($fields['fields']['SECTION_ID']))
628 {
629 $query->whereIn('SECTION_ID', $fields['fields']['SECTION_ID']);
630 }
631
632 if (isset($fields['fields']['ATTENDEES']) && is_array($fields['fields']['ATTENDEES']))
633 {
634 if (isset($fields['fields']['MEETING_STATUS']))
635 {
636 $query
637 ->registerRuntimeField(
638 'EVENT_THIRD',
639 new ReferenceField(
640 'EVENT_THIRD',
641 EventTable::getEntity(),
642 Join::on('ref.PARENT_ID', 'this.ID'),
643 ['join_type' => Join::TYPE_LEFT]
644 )
645 )
646 ->whereIn('EVENT_THIRD.OWNER_ID', $fields['fields']['ATTENDEES'])
647 ;
648 }
649 else
650 {
651 $query->whereIn('EVENT_SECOND.OWNER_ID', $fields['fields']['ATTENDEES']);
652 }
653 $filter['IS_MEETING'] = true;
654 }
655
656 if (isset($fields['search']) && $fields['search'])
657 {
658 $filter[(\CCalendarEvent::isFullTextIndexEnabled() ? '*' : '*%').'SEARCHABLE_CONTENT'] = \CCalendarEvent::prepareToken($fields['search']);
659 }
660
661 [$filter, $parseRecursion] = self::filterByDate($fields, $filter);
662
663 $eventsFromQuery = $query->exec();
664
665 while ($event = $eventsFromQuery->Fetch())
666 {
667 $filter['ID'][] = (int)$event['PARENT_ID'];
668 }
669
670 if (isset($filter['ID']))
671 {
672 $filter['ID'] = array_unique($filter['ID']);
673
674 $entries = \CCalendarEvent::GetList(
675 [
676 'arFilter' => $filter,
677 'fetchAttendees' => true,
678 'parseRecursion' => $parseRecursion,
679 'maxInstanceCount' => 50,
680 'preciseLimits' => $parseRecursion,
681 'userId' => $userId,
682 'fetchMeetings' => true,
683 'fetchSection' => true,
684 'setDefaultLimit' => false
685 ]
686 );
687 }
688 $entries = self::applyAccessRestrictions($entries);
689 $entries = self::filterByShowDeclined($entries);
690
691 return [
692 'result' => true,
693 'entries' => $entries,
694 'counters' => false
695 ];
696 }
697
703 private static function filterByDate($fields, array $filter): array
704 {
705 $parseRecursion = false;
706 $fromTs = 0;
707 $toTs = 0;
708 if (isset($fields['fields']['DATE_FROM']))
709 {
710 $fromTs = \CCalendar::Timestamp($fields['fields']['DATE_FROM'], true, false);
711 $filter['FROM_LIMIT'] = \CCalendar::Date($fromTs, false);
712 }
713 else if (!($filter['FROM_LIMIT'] ?? null))
714 {
715 $filter['FROM_LIMIT'] = \CCalendar::Date(time() - 31 * 12 * 24 * 3600, false);
716 }
717
718 if (isset($fields['fields']['DATE_TO']))
719 {
720 $toTs = \CCalendar::Timestamp($fields['fields']['DATE_TO'], true, false);
721 $filter['TO_LIMIT'] = \CCalendar::Date($toTs, false);
722 if ($fromTs && $toTs < $fromTs)
723 {
724 $filter['TO_LIMIT'] = $filter['FROM_LIMIT'];
725 }
726 }
727
728 if ($fromTs && $toTs && $fromTs <= $toTs)
729 {
730 $parseRecursion = true;
731 }
732
733 return [
734 $filter,
735 $parseRecursion
736 ];
737 }
738
743 private static function applyAccessRestrictions(array $events): array
744 {
745 foreach ($events as $i => $event)
746 {
747 if (
748 isset($event['IS_ACCESSIBLE_TO_USER'])
749 && $event['IS_ACCESSIBLE_TO_USER'] === false
750 )
751 {
752 unset($events[$i]);
753 }
754 }
755
756 return array_values($events);
757 }
758
759 public static function filterByShowDeclined(array $entries): array
760 {
762 $optionShowDeclined = $settings['showDeclined'];
763
764 return array_values(array_filter($entries, static function($entry) use ($optionShowDeclined) {
765 $hideDeclinedEntry = (!$optionShowDeclined || (int)$entry['OWNER_ID'] !== \CCalendar::GetUserId());
766 return !($hideDeclinedEntry && $entry['MEETING_STATUS'] === 'N');
767 }));
768 }
769}
$connection
Определения actionsdefinitions.php:38
$type
Определения options.php:106
if(!is_object($USER)||! $USER->IsAuthorized()) $userId
Определения check_mail.php:18
static getFilterCompanyData(string $type, int $userId, int $ownerId, $fields)
Определения calendarfilter.php:569
static getFilterData(array $params)
Определения calendarfilter.php:342
static getPresets($type)
Определения calendarfilter.php:89
static array $filters
Определения calendarfilter.php:23
static getSectionsForFilter(string $type, ?string $preset, ?int $ownerId, ?int $userId)
Определения calendarfilter.php:280
static getAvailableFields()
Определения calendarfilter.php:29
static getFilterId($type, $ownerId, $userId)
Определения calendarfilter.php:53
static getFilterUserData(string $type, int $userId, int $ownerId, $fields)
Определения calendarfilter.php:384
static filterByShowDeclined(array $entries)
Определения calendarfilter.php:759
static resolveFilterFields(string $filterId)
Определения calendarfilter.php:142
static setFilterId($filterId)
Определения calendarfilter.php:79
static getValues(int $userId, array $groupIds=[])
Определения countersmanager.php:22
static get($userId=null)
Определения usersettings.php:86
static getHiddenSections($userId=false, $options=[])
Определения usersettings.php:254
Определения emoji.php:10
</td ></tr ></table ></td ></tr >< tr >< td class="bx-popup-label bx-width30"><?=GetMessage("PAGE_NEW_TAGS")?> array( $site)
Определения file_new.php:804
$result
Определения get_property_values.php:14
$query
Определения get_search.php:11
$filter
Определения iblock_catalog_list.php:54
if(!is_null($config))($config as $configItem)(! $configItem->isVisible()) $code
Определения options.php:195
$settings
Определения product_settings.php:43
$event
Определения prolog_after.php:141
return false
Определения prolog_main_admin.php:185
if(empty($signedUserToken)) $key
Определения quickway.php:257
$filterOptions
Определения options.php:63
$i
Определения factura.php:643
if($inWords) echo htmlspecialcharsbx(Number2Word_Rus(roundEx($totalVatSum $params['CURRENCY']
Определения template.php:799
$counters
Определения options.php:100
$fields
Определения yandex_run.php:501