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/bizproc/lib/service/

Upload File :
current_dir [ Writeable] document_root [ Writeable]

 

Command :


[ Back ]     

Current File : /home/bitrix/ext_www/rospirotorg.ru/bitrix/modules/bizproc/lib/service/user.php
<?php
namespace Bitrix\Bizproc\Service;

use Bitrix\Bizproc\FieldType;
use Bitrix\Main;
use Bitrix\Main\Localization\Loc;
use Bitrix\HumanResources\Service\Container;
use Bitrix\HumanResources\Item\NodeMember;
use Bitrix\HumanResources\Compatibility\Utils\DepartmentBackwardAccessCode;
use Bitrix\Main\UserGroupTable;

class User extends \CBPRuntimeService
{
	protected const DEPARTMENT_MODULE_ID = 'intranet';
	protected const DEPARTMENT_OPTION_NAME = 'iblock_structure';

	protected array $users = [];

	public function getUserDepartments(int $userId): array
	{
		// it's OK for now to use old api
		return $this->getUserDepartmentsOld($userId);
	}

	public function getUserInfo(int $userId): ?array
	{
		if ($userId <= 0)
		{
			return null;
		}

		if (isset($this->users[$userId]))
		{
			return $this->users[$userId];
		}

		$userFields = $this->getUserUserFields();

		return $this->loadUser($userId, $userFields);
	}

	public function getUserExtendedFields(): array
	{
		$fields = $this->getUserUserFields();

		if ($this->canUseIntranet())
		{
			$fields['UF_DEPARTMENT'] = [
				'Name' => Loc::getMessage('BP_SERVICE_USER_DEPARTMENT_1'),
				'Type' => 'int',
				'Multiple' => true,
			];

			$fields['UF_DEPARTMENT_PRINTABLE'] = [
				'Name' => Loc::getMessage('BP_SERVICE_USER_DEPARTMENT_PRINTABLE_1'),
				'Type' => 'string',
				'Multiple' => true,
			];

			$fields['IS_ABSENT'] = [
				'Name' => Loc::getMessage('BP_SERVICE_USER_IS_ABSENT'),
				'Type' => 'bool',
			];

			if ($this->canUseIblockApi() || $this->canUseHumanResources())
			{
				$fields['UF_HEAD'] = [
					'Name' => Loc::getMessage('BP_SERVICE_USER_HEAD'),
					'Type' => 'user',
					'Multiple' => true,
				];
			}
		}

		if ($this->canUseTimeman())
		{
			$fields['TIMEMAN_STATUS'] = [
				'Name' => Loc::getMessage('BP_SERVICE_USER_TIMEMAN_STATUS'),
				'Type' => 'select',
				'Options' => [
					'EXPIRED' => Loc::getMessage('BP_SERVICE_USER_TIMEMAN_STATUS_EXPIRED'),
					'OPENED' => Loc::getMessage('BP_SERVICE_USER_TIMEMAN_STATUS_OPENED'),
					'PAUSED' => Loc::getMessage('BP_SERVICE_USER_TIMEMAN_STATUS_PAUSED'),
					'CLOSED' => Loc::getMessage('BP_SERVICE_USER_TIMEMAN_STATUS_CLOSED'),
				],
			];
		}

		if ($this->canUseHumanResources())
		{
			$fields['HR_NODE_IDS'] = [
				'Name' => Loc::getMessage('BP_SERVICE_USER_HR_NODE_IDS'),
				'Type' => 'int',
				'Multiple' => true,
			];
			$fields['HR_NODE'] = [
				'Name' => Loc::getMessage('BP_SERVICE_USER_HR_NODE'),
				'Type' => 'user',
				'Multiple' => true,
			];
		}

		return $fields;
	}

	public function getUserBaseFields(): array
	{
		return [
			'ACTIVE' => [
				'Name' => Loc::getMessage('BP_SERVICE_USER_ACTIVE'),
				'Type' => 'bool',
			],
			'EMAIL' => [
				'Name' => Loc::getMessage('BP_SERVICE_USER_EMAIL'),
				'Type' => 'string',
			],
			'WORK_PHONE' => [
				'Name' => Loc::getMessage('BP_SERVICE_USER_WORK_PHONE'),
				'Type' => 'string',
			],
			'PERSONAL_MOBILE' => [
				'Name' => Loc::getMessage('BP_SERVICE_USER_PERSONAL_MOBILE'),
				'Type' => 'string',
			],
			'UF_PHONE_INNER' => [
				'Name' => Loc::getMessage('BP_SERVICE_USER_UF_PHONE_INNER'),
				'Type' => 'string',
			],
			'LOGIN' => [
				'Name' => Loc::getMessage('BP_SERVICE_USER_LOGIN'),
				'Type' => 'string',
			],
			'NAME' => [
				'Name' => Loc::getMessage('BP_SERVICE_USER_NAME'),
				'Type' => 'string',
			],
			'LAST_NAME' => [
				'Name' => Loc::getMessage('BP_SERVICE_USER_LAST_NAME'),
				'Type' => 'string',
			],
			'SECOND_NAME' => [
				'Name' => Loc::getMessage('BP_SERVICE_USER_SECOND_NAME'),
				'Type' => 'string',
			],
			'WORK_POSITION' => [
				'Name' => Loc::getMessage('BP_SERVICE_USER_WORK_POSITION'),
				'Type' => 'string',
			],
			'PERSONAL_BIRTHDAY' => [
				'Name' => Loc::getMessage('BP_SERVICE_USER_PERSONAL_BIRTHDAY'),
				'Type' => 'date',
			],
			'PERSONAL_WWW' => [
				'Name' => Loc::getMessage('BP_SERVICE_USER_PERSONAL_WWW'),
				'Type' => 'string',
			],
			'PERSONAL_CITY' => [
				'Name' => Loc::getMessage('BP_SERVICE_USER_PERSONAL_CITY'),
				'Type' => 'string',
			],
			'UF_DEPARTMENT' => [
				'Name' => Loc::getMessage('BP_SERVICE_USER_DEPARTMENT_1'),
				'Type' => 'int',
				'Multiple' => true,
			],
			'UF_SKYPE' => [
				'Name' => Loc::getMessage('BP_SERVICE_USER_UF_SKYPE'),
				'Type' => 'string',
			],
			'UF_TWITTER' => [
				'Name' => Loc::getMessage('BP_SERVICE_USER_UF_TWITTER'),
				'Type' => 'string',
			],
			'UF_FACEBOOK' => [
				'Name' => Loc::getMessage('BP_SERVICE_USER_UF_FACEBOOK'),
				'Type' => 'string',
			],
			'UF_LINKEDIN' => [
				'Name' => Loc::getMessage('BP_SERVICE_USER_UF_LINKEDIN'),
				'Type' => 'string',
			],
			'UF_XING' => [
				'Name' => Loc::getMessage('BP_SERVICE_USER_UF_XING'),
				'Type' => 'string',
			],
			'UF_WEB_SITES' => [
				'Name' => Loc::getMessage('BP_SERVICE_USER_UF_WEB_SITES'),
				'Type' => 'string',
			],
		];
	}

	public function getUserDepartmentChains(int $userId): array
	{
		$chains = [];

		foreach ($this->getUserDepartments($userId) as $departmentId)
		{
			$chains[] = $this->getDepartmentChain($departmentId);
		}

		return $chains;
	}

	public function getDepartmentChain(int $departmentId): array
	{
		if (!$this->canUseHumanResources())
		{
			return $this->getDepartmentChainOld($departmentId);
		}

		$chain = [];
		$node = $this->getDepartmentNode($departmentId);

		if ($node)
		{
			$nodes = Container::getNodeRepository()->getParentOf(
				$node,
				\Bitrix\HumanResources\Enum\DepthLevel::FULL,
			);
			foreach ($nodes as $parent)
			{
				$chain[] = DepartmentBackwardAccessCode::extractIdFromCode($parent->accessCode);
			}
		}

		return $chain;
	}

	public function getUserHeads(int $userId): array
	{
		$heads = [];
		$userDepartments = $this->getUserDepartmentChains($userId);

		foreach ($userDepartments as $chain)
		{
			foreach ($chain as $deptId)
			{
				$departmentHead = $this->getDepartmentHead($deptId);

				if (!$departmentHead || $departmentHead === $userId)
				{
					continue;
				}

				$heads[] = $departmentHead;
				break;
			}
		}

		return array_unique($heads);
	}

	public function getDepartmentHead(int $departmentId): ?int
	{
		if (!$this->canUseHumanResources())
		{
			return $this->getDepartmentHeadOld($departmentId);
		}

		$node = $this->getDepartmentNode($departmentId);
		if (!$node)
		{
			return null;
		}

		$head = current(Container::getNodeMemberService()->getDefaultHeadRoleEmployees($node->id)->getItemMap());

		return $head->entityId ?? null;
	}

	public function getUserSchedule(int $userId): Sub\UserSchedule
	{
		return new Sub\UserSchedule($userId);
	}

	protected function getDepartmentIblockId(): int
	{
		return (int) Main\Config\Option::get(
			static::DEPARTMENT_MODULE_ID,
			static::DEPARTMENT_OPTION_NAME
		);
	}

	private function canUseHumanResources(): bool
	{
		return Main\Loader::includeModule('humanresources');
	}

	private function canUseIblockApi()
	{
		return Main\Loader::includeModule('iblock');
	}

	private function canUseIntranet()
	{
		return Main\Loader::includeModule('intranet');
	}

	private function canUseTimeman()
	{
		return \CBPHelper::isWorkTimeAvailable();
	}

	public function getUserUserFields(): array
	{
		static $fields;

		if (isset($fields))
		{
			return $fields;
		}

		$fields = [];

		$userFields = Main\UserFieldTable::getList([
			'select' => array_merge(
				['ID', 'FIELD_NAME', 'USER_TYPE_ID', 'MULTIPLE'],
				Main\UserFieldTable::getLabelsSelect()
			),
			'filter' => [
				'=ENTITY_ID' => 'USER',
				'%=FIELD_NAME' => 'UF_USR_%',
			],
			'runtime' => [
				Main\UserFieldTable::getLabelsReference('LABELS', \LANGUAGE_ID),
			],
		])->fetchAll();


		foreach ($userFields as $field)
		{
			$fieldName = $field['FIELD_NAME'];
			$fieldType = FieldType::convertUfType($field['USER_TYPE_ID']) ?? "UF:{$field['USER_TYPE_ID']}";

			$name = empty($field['LIST_COLUMN_LABEL']) ? $field['FIELD_NAME'] : $field['LIST_COLUMN_LABEL'];

			$fields[$fieldName] = [
				'Name' => $name,
				'Type' => $fieldType,
				'Multiple' => $field['MULTIPLE'] === 'Y',
			];

			if ($fields[$fieldName]['Type'] === 'select')
			{
				$fieldData = Main\UserFieldTable::getFieldData($field['ID']);
				$fields[$fieldName]['Options'] = array_combine(
					array_column($fieldData['ENUM'], 'XML_ID'),
					array_column($fieldData['ENUM'], 'VALUE'),
				);
				$fields[$fieldName]['Settings'] = ['ENUM' => $fieldData['ENUM']];
			}
		}

		return $fields;
	}

	public function extractUsersFromDepartment(int $departmentId, bool $recursive = false): ?array
	{
		if (!$this->canUseHumanResources())
		{
			return $this->extractUsersFromDepartmentOld($departmentId, $recursive);
		}

		$node = $this->getDepartmentNode($departmentId);
		if (!$node)
		{
			return null;
		}

		return $this->extractUsersFromHrNode($node->id, $recursive);
	}

	public function extractUsersFromGroup(int $groupId): array
	{
		if ($groupId <= 0)
		{
			return [];
		}

		$userIds =
			array_column(
				UserGroupTable::query()
					->setSelect(['USER_ID'])
					->where('GROUP_ID', $groupId)
					->setOrder(['USER_ID' => 'ASC'])
					->exec()
					->fetchAll(),
				'USER_ID'
			)
		;

		Main\Type\Collection::normalizeArrayValuesByInt($userIds, false);

		return $userIds;
	}

	public function extractUsersFromAllDepartments(): bool | array
	{
		if (!$this->canUseHumanResources())
		{
			return $this->extractUsersFromAllDepartmentsOld();
		}

		$rootNode = \Bitrix\HumanResources\Util\StructureHelper::getRootStructureDepartment();
		if ($rootNode)
		{
			$employees = Container::getNodeMemberService()->getAllEmployees($rootNode->id, true);

			$result = array_map(static fn(NodeMember $item) => $item->entityId, [...$employees->getItemMap()]);
			Main\Type\Collection::normalizeArrayValuesByInt($result);

			return $result;
		}

		return false;
	}

	/**
	 * @deprecated
	 * @return bool|array
	 * @throws Main\LoaderException
	 */
	private function extractUsersFromAllDepartmentsOld(): bool | array
	{
		if (Main\Loader::includeModule('intranet'))
		{
			$result = [];
			$iterator = \CUser::GetList(
				'ID',
				'ASC',
				['ACTIVE' => 'Y', '>UF_DEPARTMENT' => 0],
				['FIELDS' => ['ID']]
			);
			while ($user = $iterator->Fetch())
			{
				$result[] = (int)$user['ID'];
			}

			return $result;
		}

		return false;
	}

	public function extractUsersFromSocNetGroup(int $groupId, string $role = 'K'): bool | array
	{
		if (Main\Loader::includeModule('socialnetwork'))
		{
			$result = [];
			$iterator = \CSocNetUserToGroup::GetList(
				['USER_ID' => 'ASC'],
				['=GROUP_ID' => $groupId, '<=ROLE' => $role, 'USER_ACTIVE' => 'Y'],
				false,
				false,
				['USER_ID']
			);
			while ($user = $iterator->Fetch())
			{
				$result[] = (int)$user['USER_ID'];
			}

			return $result;
		}

		return false;
	}

	public function extractUsersFromHrNode(int $nodeId, bool $recursive = true): ?array
	{
		if ($nodeId <= 0 || !$this->canUseHumanResources())
		{
			return null;
		}

		$employeesCollection = Container::getNodeMemberService()->getPagedEmployees($nodeId, $recursive);

		return array_values(
			array_unique(
				array_map(static fn(NodeMember $item) => $item->entityId, [...$employeesCollection->getItemMap()])
			)
		);
	}

	private function convertValues(array &$values, array $userFields): void
	{
		foreach ($userFields as $id => $field)
		{
			if ($field['Type'] === 'bool')
			{
				$values[$id] = \CBPHelper::getBool($values[$id]) ? 'Y' : 'N';
			}
			elseif ($field['Type'] === 'select')
			{
				$values[$id] = $this->convertSelectValue($values[$id], $field);
			}
		}

		if (!empty($values['UF_DEPARTMENT']))
		{
			$values['UF_DEPARTMENT_PRINTABLE'] = $this->loadDepartmentNames($values['UF_DEPARTMENT']);
		}
	}

	private function convertSelectValue($value, $field)
	{
		$enumIds = array_combine(
			array_column($field['Settings']['ENUM'], 'XML_ID'),
			array_column($field['Settings']['ENUM'], 'ID'),
		);

		if (is_array($value))
		{
			$xmlIds = [];
			foreach ($value as $val)
			{
				$xmlIds[] = array_search($val, $enumIds);
			}

			return array_filter($xmlIds, fn($id) => $id !== false);
		}

		$xmlId = array_search($value, $enumIds);

		return $xmlId !== false ? $xmlId : '';
	}

	private function convertUserValue($value): array
	{
		$users = [];

		$value = is_array($value) ? $value : [$value];
		foreach ($value as $userId)
		{
			if (is_int($userId))
			{
				$users[] = 'user_' . $userId;
			}
		}

		return $users;
	}

	private function loadUser(int $userId, array $fields): ?array
	{
		$dbUsers = \CUser::GetList(
			'id',
			'asc',
			['ID_EQUAL_EXACT' => $userId],
			[
				'FIELDS' => [
					'ID',
					'EMAIL',
					'WORK_PHONE',
					'PERSONAL_MOBILE',
					'PERSONAL_BIRTHDAY',
					'LOGIN',
					'ACTIVE',
					'NAME',
					'LAST_NAME',
					'SECOND_NAME',
					'WORK_POSITION',
					'PERSONAL_WWW',
					'PERSONAL_CITY',
				],
				'SELECT' => [
					'UF_DEPARTMENT',
					'UF_SKYPE',
					'UF_TWITTER',
					'UF_FACEBOOK',
					'UF_LINKEDIN',
					'UF_XING',
					'UF_WEB_SITES',
					'UF_PHONE_INNER',
					...array_keys($fields),
				],
			]
		);

		$user = $dbUsers->fetch();

		if (is_array($user))
		{
			if ($this->canUseHumanResources())
			{
				$user['HR_NODE_IDS'] =
					array_map(
						static fn (\Bitrix\HumanResources\Item\Node $node) => $node->id,
						[...Container::getNodeRepository()->findAllByUserId($userId)->getItemMap()]
					)
				;
				$user['HR_NODE'] = array_map(static fn(int $id) => 'group_hr' . $id, $user['HR_NODE_IDS']);
			}

			$this->convertValues($user, $fields);
			$this->users[$userId] = $user;

			$schedule = $this->getUserSchedule($userId);
			$this->users[$userId]['IS_ABSENT'] = $schedule->isAbsent();
			$this->users[$userId]['TIMEMAN_STATUS'] = $schedule->getWorkDayStatus();
			$this->users[$userId]['UF_HEAD'] = $this->convertUserValue($this->getUserHeads($userId));

			return $this->users[$userId];
		}

		return null;
	}

	private function loadDepartmentNames(array $ids): array
	{
		if (!$this->canUseHumanResources())
		{
			return $this->loadDepartmentNamesOld($ids);
		}

		$codes = array_map(
			static fn($id) => DepartmentBackwardAccessCode::makeById($id),
			$ids
		);

		$collection = Container::getNodeRepository()->findAllByAccessCodes($codes);
		$names = [];
		foreach ($collection as $node)
		{
			$names[DepartmentBackwardAccessCode::extractIdFromCode($node->accessCode)] = $node->name;
		}

		return array_values(array_filter(
			array_map(
				static fn($id) => $names[$id] ?? null,
				$ids
			)
		));
	}

	private function getDepartmentNode(int $departmentId): ?\Bitrix\HumanResources\Item\Node
	{
		return Container::getNodeRepository()->getByAccessCode(DepartmentBackwardAccessCode::makeById($departmentId));
	}

	/**
	 * @deprecated
	 * @param int $departmentId
	 * @param bool $recursive
	 * @return array|null
	 */
	private function extractUsersFromDepartmentOld(int $departmentId, bool $recursive = false): ?array
	{
		if (!$this->canUseIntranet() || !$this->canUseIblockApi())
		{
			return null;
		}

		$iblockId = $this->getDepartmentIblockId();
		$departmentIds = [$departmentId];

		if ($recursive)
		{
			$iterator = \CIBlockSection::GetList(
				['ID' => 'ASC'],
				['=IBLOCK_ID' => $iblockId, 'ID' => $departmentId],
				false,
				['ID', 'LEFT_MARGIN', 'RIGHT_MARGIN', 'DEPTH_LEVEL']
			);
			$section = $iterator->fetch();
			$filter = [
				'=IBLOCK_ID' => $iblockId,
				">LEFT_MARGIN" => $section["LEFT_MARGIN"],
				"<RIGHT_MARGIN" => $section["RIGHT_MARGIN"],
				">DEPTH_LEVEL" => $section['DEPTH_LEVEL'],
			];
			$iterator = \CIBlockSection::GetList(["left_margin" => "asc"], $filter, false, ['ID']);
			while ($section = $iterator->fetch())
			{
				$departmentIds[] = $section['ID'];
			}
			unset($iterator, $section, $filter);
		}
		$result = [];
		$iterator = \CUser::GetList("departmentId", "asc",
			['ACTIVE' => 'Y', 'UF_DEPARTMENT' => $departmentIds],
			['FIELDS' => ['ID']]
		);
		while ($user = $iterator->fetch())
		{
			$result[] = (int)$user['ID'];
		}

		return $result;
	}

	/**
	 * @deprecated
	 * @param array $ids
	 * @return array
	 * @throws Main\LoaderException
	 */
	private function loadDepartmentNamesOld(array $ids): array
	{
		$names = [];

		if (!Main\Loader::includeModule('intranet') || !Main\Loader::includeModule('iblock'))
		{
			return $names;
		}

		$iblockId = $this->getDepartmentIblockId();

		$iterator = \CIBlockSection::GetList(
			['ID' => 'ASC'],
			[
				'=IBLOCK_ID' => $iblockId,
				'ID' => $ids,
				'CHECK_PERMISSIONS' => 'N',
			],
			false,
			['ID', 'NAME']
		);

		while ($row = $iterator->fetch())
		{
			$names[$row['ID']] = $row['NAME'];
		}

		return array_values(array_filter(
			array_map(
				fn($id) => $names[$id] ?? null,
				$ids
			)
		));
	}

	/**
	 * @deprecated
	 * @param int $userId
	 * @return array
	 */
	private function getUserDepartmentsOld(int $userId): array
	{
		if (isset($this->users[$userId]['UF_DEPARTMENT']))
		{
			return is_array($this->users[$userId]['UF_DEPARTMENT']) ? $this->users[$userId]['UF_DEPARTMENT'] : [];
		}

		$departments = [];
		$result = \CUser::getList(
			'id', 'asc',
			['ID_EQUAL_EXACT' => $userId],
			['FIELDS' => ['ID'], 'SELECT' => ['UF_DEPARTMENT']]
		);

		if ($user = $result->fetch())
		{
			if (isset($user['UF_DEPARTMENT']))
			{
				$user['UF_DEPARTMENT'] = (array) $user['UF_DEPARTMENT'];
				foreach ($user['UF_DEPARTMENT'] as $dpt)
				{
					$departments[] = (int) $dpt;
				}
			}
		}

		return $departments;
	}

	/**
	 * @deprecated
	 * @param int $departmentId
	 * @return array
	 */
	private function getDepartmentChainOld(int $departmentId): array
	{
		$chain = [];

		if (!$this->canUseIblockApi())
		{
			return $chain;
		}

		$departmentIblockId = $this->getDepartmentIblockId();
		$chain = \CIBlockSection::getNavChain($departmentIblockId, $departmentId, ['ID'], true);

		$chain = array_map(
			static fn($value) => (int)$value['ID'],
			$chain
		);

		return array_reverse($chain);
	}

	/**
	 * @deprecated
	 * @param int $departmentId
	 * @return int|null
	 */
	private function getDepartmentHeadOld(int $departmentId): ?int
	{
		if (!$this->canUseIblockApi())
		{
			return null;
		}

		$departmentIblockId = $this->getDepartmentIblockId();
		$sectionResult = \CIBlockSection::GetList(
			[],
			['IBLOCK_ID' => $departmentIblockId, 'ID' => $departmentId],
			false,
			['ID', 'UF_HEAD']
		);
		$section = $sectionResult->fetch();

		return $section ? (int) $section['UF_HEAD'] : null;
	}
}

Youez - 2016 - github.com/yon3zu
LinuXploit