403Webshell
Server IP : 80.87.202.40  /  Your IP : 216.73.216.169
Web Server : Apache
System : Linux rospirotorg.ru 5.14.0-539.el9.x86_64 #1 SMP PREEMPT_DYNAMIC Thu Dec 5 22:26:13 UTC 2024 x86_64
User : bitrix ( 600)
PHP Version : 8.2.27
Disable Function : NONE
MySQL : OFF |  cURL : ON |  WGET : ON |  Perl : ON |  Python : OFF |  Sudo : ON |  Pkexec : ON
Directory :  /home/bitrix/ext_www/rospirotorg.ru/bitrix/modules/calendar/lib/ui/

Upload File :
current_dir [ Writeable] document_root [ Writeable]

 

Command :


[ Back ]     

Current File : /home/bitrix/ext_www/rospirotorg.ru/bitrix/modules/calendar/lib/ui/calendarfilter.php
<?php

namespace Bitrix\Calendar\Ui;

use Bitrix\Calendar\Core\Event\Tools\Dictionary;
use Bitrix\Calendar\Internals\EventTable;
use Bitrix\Calendar\UserSettings;
use Bitrix\Main\Application;
use Bitrix\Main\Entity\ReferenceField;
use Bitrix\Main\Localization\Loc;
use Bitrix\Main\ORM\Query\Join;
use Bitrix\Main\Text\Emoji;

class CalendarFilter
{
	public const PRESET_INVITED = 'filter_calendar_meeting_status_q';
	private const PRESET_HOST = 'filter_calendar_host';
	private const PRESET_ATTENDEE = 'filter_calendar_attendee';
	private const PRESET_DECLINED = 'filter_calendar_declined';

	protected static $filterId = '';

	protected static array $filters;

	/**
	 * Get available fields in filter.
	 * @return array
	 */
	protected static function getAvailableFields(): array
	{
		return [
			'CREATED_BY',
			'ATTENDEES',
			'IS_MEETING',
			'IS_RECURSIVE',
			'MEETING_STATUS',
			'MEETING_HOST',
			'DATE_FROM',
			'DATE_TO',
			'SECTION_ID',
			'FROM_LIMIT',
			'TO_LIMIT',
		];
	}

	/**
	 * @param $type
	 * @param $ownerId
	 * @param $userId
	 *
	 * @return string
	 */
	public static function getFilterId($type, $ownerId, $userId): string
	{
		static::$filterId = 'calendar-filter';
		if ($type === 'user' && (int)$ownerId === (int)$userId)
		{
			static::$filterId = 'calendar-filter-personal';
		}
		else if (
			$type === 'company_calendar'
			|| $type === 'calendar_company'
			|| $type === 'company'
		)
		{
			static::$filterId = 'calendar-filter-company';
		}
		else if ($type === 'group')
		{
			static::$filterId = 'calendar-filter-group';
		}

		return static::$filterId;
	}

	/**
	 * @param $filterId
	 */
	public static function setFilterId($filterId)
	{
		static::$filterId = $filterId;
	}

	/**
	 * @param $type
	 *
	 * @return array
	 */
	public static function getPresets($type): array
	{
		$presets = [];
		if ($type === Dictionary::CALENDAR_TYPE['user'] || $type === Dictionary::CALENDAR_TYPE['group'])
		{
			$presets[self::PRESET_INVITED] = [
				'id' => self::PRESET_INVITED,
				'name' => Loc::getMessage('CALENDAR_PRESET_MEETING_STATUS_Q'),
				'default' => false,
				'fields' => [
					'IS_MEETING' => 'Y',
					'MEETING_STATUS' => 'Q',
				]
			];
		}

		$presets[self::PRESET_HOST] = [
			'id' => self::PRESET_HOST,
			'name' => Loc::getMessage('CALENDAR_PRESET_I_AM_HOST'),
			'default' => false,
			'fields' => [
				'MEETING_STATUS' => 'H',
			]
		];

		$presets[self::PRESET_ATTENDEE] = [
			'id' => self::PRESET_ATTENDEE,
			'name' => Loc::getMessage('CALENDAR_PRESET_I_AM_ATTENDEE'),
			'default' => false,
			'fields' => [
				'IS_MEETING' => 'Y',
				'MEETING_STATUS' => 'Y',
			]
		];

		$presets[self::PRESET_DECLINED] = [
			'id' => self::PRESET_DECLINED,
			'name' => Loc::getMessage('CALENDAR_PRESET_I_DECLINED'),
			'default' => false,
			'fields' => [
				'IS_MEETING' => 'Y',
				'MEETING_STATUS' => 'N',
			]
		];

		return $presets;
	}

	/**
	 * @param string $filterId
	 *
	 * @return array
	 */
	public static function resolveFilterFields(string $filterId): array
	{
		$filterOptions = new \Bitrix\Main\UI\Filter\Options($filterId);
		$fields = $filterOptions->getFilter();

		$preset = $fields['PRESET_ID'] ?? null;
		$meetingStatus = $fields['MEETING_STATUS'] ?? null;
		if ($meetingStatus === 'Q')
		{
			$preset = self::PRESET_INVITED;
		}
		if ($meetingStatus === 'Y')
		{
			$preset = self::PRESET_ATTENDEE;
		}
		if ($meetingStatus === 'N')
		{
			$preset = self::PRESET_DECLINED;
		}

		$result = [
			'search' => $filterOptions->getSearchString(),
			'presetId' => $preset,
			'fields' => []
		];
		$connection = Application::getConnection();
		$sqlHelper = $connection->getSqlHelper();

		$fieldNames = self::getAvailableFields();
		foreach ($fields as $key => $value)
		{
			if ($key === 'DATE_from')
			{
				$result['fields']['DATE_FROM'] = $value;
			}
			else if ($key === 'DATE_to')
			{
				$result['fields']['DATE_TO'] = $value;
			}
			else if ($key === 'ATTENDEES' || $key === 'CREATED_BY' || $key === 'SECTION_ID')
			{
				$valueList = [];
				foreach ($value as $code)
				{
					$valueList[] = (int)$code;
				}
				$result['fields'][$key] = $valueList;
			}
			else if ($key === 'MEETING_STATUS')
			{
				$result['fields']['MEETING_STATUS'] = $sqlHelper->forSql($value);
			}
			else if (in_array($key, $fieldNames, true))
			{
				$result['fields'][$key] = $value;
			}
		}

		return $result;
	}

	/**
	 * @return array
	 */
	public static function getFilters(): array
	{
		if (empty(static::$filters))
		{
			static::$filters['CREATED_BY'] = [
				'id' => 'CREATED_BY',
				'name' => Loc::getMessage('CALENDAR_FILTER_CREATED_BY'),
				'type' => 'entity_selector',
				'partial' => true,
				'params' => [
					'multiple' => 'Y',
					'dialogOptions' => [
						'height' => 240,
						'context' => 'filter',
						'entities' => [
							[
								'id' => 'user',
								'options' => [
									'inviteEmployeeLink' => false
								],
							]
						]
					],
				],
			];

			static::$filters['ATTENDEES'] = [
				'id' => 'ATTENDEES',
				'name' => Loc::getMessage('CALENDAR_FILTER_ATTENDEES'),
				'type' => 'entity_selector',
				'partial' => true,
				'params' => [
					'multiple' => 'Y',
					'dialogOptions' => [
						'height' => 270,
						'context' => 'filter',
						'entities' => [
							[
								'id' => 'user',
								'options' => [
									'inviteEmployeeLink' => false
								],
							],
						]
					],
				],
			];

			static::$filters['MEETING_STATUS'] = [
				'id' => 'MEETING_STATUS',
				'name' => Loc::getMessage('CALENDAR_FILTER_MEETING_STATUS_ME'),
				'type' => 'list',
				'params' => [
					'multiple' => 'N'
				],
				'items' => [
					'H' => Loc::getMessage('CALENDAR_FILTER_MEETING_STATUS_H'),
					'Q' => Loc::getMessage('CALENDAR_FILTER_MEETING_STATUS_Q'),
					'Y' => Loc::getMessage('CALENDAR_FILTER_MEETING_STATUS_Y'),
					'N' => Loc::getMessage('CALENDAR_FILTER_MEETING_STATUS_N'),
				]
			];

			static::$filters['DATE'] = [
				'id' => 'DATE',
				'name' => Loc::getMessage('CALENDAR_FILTER_DATE'),
				'type' => 'date',
				'default' => true,
			];
		}

		return static::$filters;
	}

	public static function getSectionsForFilter(string $type, ?string $preset, ?int $ownerId, ?int $userId): array
	{
		$result = [];

		if ($type === 'group' && $preset === self::PRESET_INVITED)
		{
			$sectionList = \CCalendar::getSectionList([
				'CAL_TYPE' => Dictionary::CALENDAR_TYPE['user'],
				'OWNER_ID' => array_unique([(int)$userId, 0]),
				'checkPermissions' => true,
				'getPermissions' => true,
			]);
		}
		else
		{
			$sectionList = \CCalendar::getSectionList([
				'CAL_TYPE' => $type === 'user' ? ['user', 'open_event'] : $type,
				'OWNER_ID' => array_unique([(int)$ownerId, 0]),
				'checkPermissions' => true,
				'getPermissions' => true,
			]);
		}

		$isPersonalCalendarContext = ($type === 'user' && $userId === $ownerId);

		$hiddenSections = [];
		if ($preset !== self::PRESET_INVITED)
		{
			$hiddenSections = UserSettings::getHiddenSections(
				$userId,
				[
					'type' => $type,
					'ownerId' => $ownerId,
					'isPersonalCalendarContext' => $isPersonalCalendarContext,
				]
			);
			$hiddenSections = array_map(static function($sectionId) {
				return (int)$sectionId;
			}, $hiddenSections);
		}

		foreach ($sectionList as $section)
		{
			if (in_array((int)$section['ID'], $hiddenSections, true))
			{
				continue;
			}

			$result[] = (int)$section['ID'];
		}

		return $result;
	}

	/**
	 * @param array $params
	 *
	 * @return array
	 * @throws \Bitrix\Main\ArgumentException
	 * @throws \Bitrix\Main\ObjectPropertyException
	 * @throws \Bitrix\Main\SystemException
	 */
	public static function getFilterData(array $params): array
	{
		$connection = Application::getConnection();
		$sqlHelper = $connection->getSqlHelper();
		$userId = (int)$params['userId'];
		$ownerId = (int)$params['ownerId'];
		$type = $sqlHelper->forSql($params['type']);

		$fields = self::resolveFilterFields(
			self::getFilterId($type, $ownerId, $userId)
		);
		$fields['fields']['SECTION_ID'] = self::getSectionsForFilter(
			$params['type'],
			$fields['presetId'],
			$params['ownerId'],
			$params['userId'],
		);

		if (
			$type === 'company_calendar'
			|| $type === 'calendar_company'
			|| $type === 'company'
			|| $type === 'group'
		)
		{
			return self::getFilterCompanyData($type, $userId, $ownerId, $fields);
		}

		return self::getFilterUserData($type, $userId, $ownerId, $fields);
	}

	/**
	 * @param string $type
	 * @param int $userId
	 * @param int $ownerId
	 * @param $fields
	 *
	 * @return array
	 * @throws \Bitrix\Main\ArgumentException
	 * @throws \Bitrix\Main\ObjectPropertyException
	 * @throws \Bitrix\Main\SystemException
	 */
	public static function getFilterUserData(string $type, int $userId, int $ownerId, $fields): array
	{
		$counters = false;
		$entries = [];
		$filter = [
			'OWNER_ID' => $ownerId,
			'CAL_TYPE' => $type === 'user' ? ['user', 'open_event'] : $type,
			'ACTIVE_SECTION' => 'Y',
		];

		if (isset($fields['fields']['IS_MEETING']))
		{
			$filter['IS_MEETING'] = $fields['fields']['IS_MEETING'] === 'Y';
		}

		if (isset($fields['fields']['MEETING_STATUS']))
		{
			$filter['MEETING_STATUS'] = $fields['fields']['MEETING_STATUS'];
			if ($filter['MEETING_STATUS'] === 'H')
			{
				unset($filter['MEETING_STATUS']);
				$filter['MEETING_HOST'] = $userId;
			}
			else
			{
				$filter['IS_MEETING'] = true;
			}

			if ($fields['presetId'] === self::PRESET_INVITED)
			{
				$filter['FROM_LIMIT'] = \CCalendar::Date(time(), false);
				$filter['TO_LIMIT'] = \CCalendar::Date(time() + \CCalendar::DAY_LENGTH * 90, false);

				\CCalendar::UpdateCounter(
					users: [$userId],
					groupIds: $type === Dictionary::CALENDAR_TYPE['group'] ? [$ownerId] : [],
				);

				$counters = CountersManager::getValues((int)$filter['OWNER_ID']);
			}
		}

		if (isset($fields['fields']['CREATED_BY']))
		{
			unset($filter['OWNER_ID'], $filter['CAL_TYPE']);
			$filter['MEETING_HOST'] = $fields['fields']['CREATED_BY'];
			// mantis: 93743
			$filter['OWNER_ID'] = $userId;
		}

		if (!empty($fields['fields']['SECTION_ID']))
		{
			$filter['SECTION'] = $fields['fields']['SECTION_ID'];
		}
		else
		{
			return [
				'result' => true,
				'entries' => $entries,
				'counters' => $counters
			];
		}

		if (isset($fields['fields']['ATTENDEES']))
		{
			$query = EventTable::query()
				->setSelect(['ID'])
				->registerRuntimeField(
					'EVENT_SECOND',
					new ReferenceField(
						'EVENT_SECOND',
						EventTable::getEntity(),
						Join::on('ref.PARENT_ID', 'this.PARENT_ID'),
						['join_type' => Join::TYPE_LEFT]
					)
				)
				->where('DELETED', 'N')
				->where('EVENT_SECOND.DELETED', 'N')
				->where('CAL_TYPE', $type)
				->where('OWNER_ID', $userId)
				->whereIn('EVENT_SECOND.OWNER_ID', $fields['fields']['ATTENDEES'])
				->exec()
			;

			while ($event = $query->fetch())
			{
				$filter['ID'][] = (int)$event['ID'];
			}

			if (!empty($filter['ID']))
			{
				$filter['ID'] = array_unique($filter['ID']);
			}
			else
			{
				$filter['ID'] = [0];
			}

			$filter['IS_MEETING'] = true;
		}

		if ($type === Dictionary::CALENDAR_TYPE['group'] && $fields['presetId'] === self::PRESET_INVITED)
		{
			$filter['OWNER_ID'] = $userId;
			$filter['CAL_TYPE'] = ['user', 'open_event'];

			$query = EventTable::query()
				->setSelect(['ID'])
				->registerRuntimeField(
					'EVENT_SECOND',
					new ReferenceField(
						'EVENT_SECOND',
						EventTable::getEntity(),
						Join::on('ref.ID', 'this.PARENT_ID'),
						['join_type' => Join::TYPE_LEFT]
					)
				)
				->where('DELETED', 'N')
				->where('EVENT_SECOND.DELETED', 'N')
				->where('CAL_TYPE', Dictionary::CALENDAR_TYPE['user'])
				->where('EVENT_SECOND.CAL_TYPE', $type)
				->where('OWNER_ID', $userId)
				->where('EVENT_SECOND.OWNER_ID', $ownerId)
				->where('MEETING_STATUS', Dictionary::MEETING_STATUS['Question'])
				->exec()
			;

			while ($event = $query->fetch())
			{
				$filter['ID'][] = (int)$event['ID'];
			}

			if (!empty($filter['ID']))
			{
				$filter['ID'] = array_unique($filter['ID']);
			}
			else
			{
				$filter['ID'] = [0];
			}
		}

		[$filter, $parseRecursion] = self::filterByDate($fields, $filter);

		if (isset($fields['search']) && $fields['search'])
		{
			$filter[(\CCalendarEvent::isFullTextIndexEnabled() ? '*' : '*%').'SEARCHABLE_CONTENT'] = \CCalendarEvent::prepareToken(Emoji::encode($fields['search']));
		}

		$entries = \CCalendarEvent::GetList(
			[
				'arFilter' => $filter,
				'fetchAttendees' => true,
				'parseRecursion' => $parseRecursion,
				'maxInstanceCount' => 50,
				'preciseLimits' => $parseRecursion,
				'userId' => $userId,
				'fetchMeetings' => true,
				'fetchSection' => true,
				'setDefaultLimit' => false
			]
		);
		if ($fields['presetId'] !== self::PRESET_DECLINED)
		{
			$entries = self::filterByShowDeclined($entries);
		}

		return [
			'result' => true,
			'entries' => $entries,
			'counters' => $counters
		];
	}

	/**
	 * @param string $type
	 * @param int $userId
	 * @param int $ownerId
	 * @param $fields
	 *
	 * @return array
	 * @throws \Bitrix\Main\ArgumentException
	 * @throws \Bitrix\Main\ObjectPropertyException
	 * @throws \Bitrix\Main\SystemException
	 */
	public static function getFilterCompanyData(string $type, int $userId, int $ownerId, $fields): array
	{
		$entries = [];

		if ($type === Dictionary::CALENDAR_TYPE['group'] && $fields['presetId'] === self::PRESET_INVITED)
		{
			return self::getFilterUserData($type, $userId, $ownerId, $fields);
		}

		$filter = [
			'CAL_TYPE' => $type,
			'ACTIVE_SECTION' => 'Y',
		];

		$query = EventTable::query()
			->setSelect(['PARENT_ID'])
			->registerRuntimeField(
				'EVENT_SECOND',
				new ReferenceField(
					'EVENT_SECOND',
					EventTable::getEntity(),
					Join::on('ref.PARENT_ID', 'this.ID'),
					['join_type' => Join::TYPE_LEFT]
				)
			)
			->where('CAL_TYPE', $type)
			->where('DELETED', 'N')
			->where('EVENT_SECOND.DELETED', 'N')
		;

		if (isset($fields['fields']['IS_MEETING']) && $fields['fields']['IS_MEETING'])
		{
			$filter['IS_MEETING'] = $fields['fields']['IS_MEETING'] === 'Y';
		}

		if (isset($fields['fields']['MEETING_STATUS']) && $fields['fields']['MEETING_STATUS'])
		{
			$query->where('EVENT_SECOND.OWNER_ID', $userId);
			if (
				$fields['fields']['MEETING_STATUS'] === 'H'
				&& !isset($fields['fields']['CREATED_BY'])
			)
			{
				unset($filter['IS_MEETING']);
				$query->where('EVENT_SECOND.MEETING_HOST', $userId);
			}
			else
			{
				$query->where('EVENT_SECOND.MEETING_STATUS', $fields['fields']['MEETING_STATUS']);
				$filter['IS_MEETING'] = true;
			}
		}

		if (isset($fields['fields']['CREATED_BY']) && is_array($fields['fields']['CREATED_BY']))
		{
			$query->whereIn('EVENT_SECOND.MEETING_HOST', $fields['fields']['CREATED_BY']);
		}

		if (isset($fields['fields']['SECTION_ID']) && is_array($fields['fields']['SECTION_ID']))
		{
			$query->whereIn('SECTION_ID',  $fields['fields']['SECTION_ID']);
		}

		if (isset($fields['fields']['ATTENDEES']) && is_array($fields['fields']['ATTENDEES']))
		{
			if (isset($fields['fields']['MEETING_STATUS']))
			{
				$query
					->registerRuntimeField(
					'EVENT_THIRD',
					new ReferenceField(
						'EVENT_THIRD',
						EventTable::getEntity(),
						Join::on('ref.PARENT_ID', 'this.ID'),
						['join_type' => Join::TYPE_LEFT]
					)
				)
					->whereIn('EVENT_THIRD.OWNER_ID', $fields['fields']['ATTENDEES'])
				;
			}
			else
			{
				$query->whereIn('EVENT_SECOND.OWNER_ID', $fields['fields']['ATTENDEES']);
			}
			$filter['IS_MEETING'] = true;
		}

		if (isset($fields['search']) && $fields['search'])
		{
			$filter[(\CCalendarEvent::isFullTextIndexEnabled() ? '*' : '*%').'SEARCHABLE_CONTENT'] = \CCalendarEvent::prepareToken($fields['search']);
		}

		[$filter, $parseRecursion] = self::filterByDate($fields, $filter);

		$eventsFromQuery = $query->exec();

		while ($event = $eventsFromQuery->Fetch())
		{
			$filter['ID'][] = (int)$event['PARENT_ID'];
		}

		if (isset($filter['ID']))
		{
			$filter['ID'] = array_unique($filter['ID']);

			$entries = \CCalendarEvent::GetList(
				[
					'arFilter' => $filter,
					'fetchAttendees' => true,
					'parseRecursion' => $parseRecursion,
					'maxInstanceCount' => 50,
					'preciseLimits' => $parseRecursion,
					'userId' => $userId,
					'fetchMeetings' => true,
					'fetchSection' => true,
					'setDefaultLimit' => false
				]
			);
		}
		$entries = self::applyAccessRestrictions($entries);
		$entries = self::filterByShowDeclined($entries);

		return [
			'result' => true,
			'entries' => $entries,
			'counters' => false
		];
	}

	/**
	 * @param $fields
	 * @param array $filter
	 * @return array
	 */
	private static function filterByDate($fields, array $filter): array
	{
		$parseRecursion = false;
		$fromTs = 0;
		$toTs = 0;
		if (isset($fields['fields']['DATE_FROM']))
		{
			$fromTs = \CCalendar::Timestamp($fields['fields']['DATE_FROM'], true, false);
			$filter['FROM_LIMIT'] = \CCalendar::Date($fromTs, false);
		}
		else if (!($filter['FROM_LIMIT'] ?? null))
		{
			$filter['FROM_LIMIT'] = \CCalendar::Date(time() - 31 * 12 * 24 * 3600, false);
		}

		if (isset($fields['fields']['DATE_TO']))
		{
			$toTs = \CCalendar::Timestamp($fields['fields']['DATE_TO'], true, false);
			$filter['TO_LIMIT'] = \CCalendar::Date($toTs, false);
			if ($fromTs && $toTs < $fromTs)
			{
				$filter['TO_LIMIT'] = $filter['FROM_LIMIT'];
			}
		}

		if ($fromTs && $toTs && $fromTs <= $toTs)
		{
			$parseRecursion = true;
		}

		return [
			$filter,
			$parseRecursion
		];
	}

	/**
	 * @param array $events
	 * @return array
	 */
	private static function applyAccessRestrictions(array $events): array
	{
		foreach ($events as $i => $event)
		{
			if (
				isset($event['IS_ACCESSIBLE_TO_USER'])
				&& $event['IS_ACCESSIBLE_TO_USER'] === false
			)
			{
				unset($events[$i]);
			}
		}

		return array_values($events);
	}

	public static function filterByShowDeclined(array $entries): array
	{
		$settings = UserSettings::get();
		$optionShowDeclined = $settings['showDeclined'];

		return array_values(array_filter($entries, static function($entry) use ($optionShowDeclined) {
			$hideDeclinedEntry = (!$optionShowDeclined || (int)$entry['OWNER_ID'] !== \CCalendar::GetUserId());
			return !($hideDeclinedEntry && $entry['MEETING_STATUS'] === 'N');
		}));
	}
}

Youez - 2016 - github.com/yon3zu
LinuXploit