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/socialnetwork/lib/item/

Upload File :
current_dir [ Writeable] document_root [ Writeable]

 

Command :


[ Back ]     

Current File : /home/bitrix/ext_www/rospirotorg.ru/bitrix/modules/socialnetwork/lib/item/usertogroup.php
<?php

/**
 * Bitrix Framework
 * @package bitrix
 * @subpackage socialnetwork
 * @copyright 2001-2012 Bitrix
 */
namespace Bitrix\Socialnetwork\Item;

use Bitrix\Main\Application;
use Bitrix\Main\Config\Option;
use Bitrix\Main\Loader;
use Bitrix\Main\Localization\Loc;
use Bitrix\Main\ModuleManager;
use Bitrix\Socialnetwork\Collab\Collab;
use Bitrix\Socialnetwork\Collab\Integration\IM\ActionMessageFactory;
use Bitrix\Socialnetwork\Collab\Integration\IM\ActionType;
use Bitrix\Socialnetwork\Collab\Url\UrlManager;
use Bitrix\Socialnetwork\Internals\Registry\GroupRegistry;
use Bitrix\Socialnetwork\WorkgroupTable;
use Bitrix\Socialnetwork\UserToGroupTable;
use Bitrix\Socialnetwork\Integration;

Loc::loadMessages(__FILE__);

class UserToGroup
{
	public const CHAT_ACTION_IN = 'in';
	public const CHAT_ACTION_OUT = 'out';

	public static function addRelationAutoMembership($params): void
	{
		global $USER;

		if (!empty($params['CURRENT_USER_ID']))
		{
			$currentUserId = (int)$params['CURRENT_USER_ID'];
		}
		elseif (is_object($USER))
		{
			$currentUserId = $USER->getId();
		}

		if ($currentUserId <= 0)
		{
			return;
		}

		static $helper = false;

		$userId = (int)($params['USER_ID'] ?? 0);
		$groupId = (int)($params['GROUP_ID'] ?? 0);
		$value = (isset($params['VALUE']) && in_array($params['VALUE'], WorkgroupTable::getAutoMembershipValuesAll(), true) ? $params['VALUE'] : 'Y');
		$notyfy = (isset($params['NOTIFY']) && $params['NOTIFY'] === "N" ? $params['NOTIFY'] : 'Y');

		if (
			$userId <= 0
			|| $groupId <= 0
		)
		{
			return;
		}

		if (!$helper)
		{
			$connection = Application::getConnection();
			$helper = $connection->getSqlHelper();
		}

		$addFields = [
			'AUTO_MEMBER' => $value,
			'USER_ID' => $userId,
			'GROUP_ID' => $groupId,
			'ROLE' => (
				isset($params['ROLE'])
				&& in_array($params['ROLE'], UserToGroupTable::getRolesAll(), true)
					? $params['ROLE']
					: UserToGroupTable::ROLE_USER
			),
			'INITIATED_BY_TYPE' => UserToGroupTable::INITIATED_BY_GROUP,
			'INITIATED_BY_USER_ID' => $currentUserId,
			'=DATE_CREATE' => $helper->getCurrentDateTimeFunction(),
			'=DATE_UPDATE' => $helper->getCurrentDateTimeFunction(),
		];

		$relationId = \CSocNetUserToGroup::add($addFields);

		if (
			!$notyfy
			|| $relationId <= 0
			|| $value !== 'Y'
		)
		{
			return;
		}

		self::notifyAutoMembership([
			'GROUP_ID' => $groupId,
			'USER_ID' => $userId,
			'RELATION_ID' => $relationId,
		]);

		self::addInfoToChat([
			'group_id' => $groupId,
			'user_id' => $userId,
			'action' => self::CHAT_ACTION_IN,
			'role' => $addFields['ROLE'],
		]);
	}

	public static function changeRelationAutoMembership($params): void
	{
		static $helper = false;

		$relationId = (int)($params['RELATION_ID'] ?? 0);
		$userId = (int)($params['USER_ID'] ?? 0);
		$groupId = (int)($params['GROUP_ID'] ?? 0);
		$value = (
			isset($params['VALUE'])
			&& in_array($params['VALUE'], WorkgroupTable::getAutoMembershipValuesAll(), true)
				? $params['VALUE']
				: 'Y'
		);
		$notyfy = (isset($params['NOTIFY']) && $params['NOTIFY'] === 'N' ? $params['NOTIFY'] : 'Y');

		if ($relationId <= 0)
		{
			return;
		}

		if (!$helper)
		{
			$connection = Application::getConnection();
			$helper = $connection->getSqlHelper();
		}

		$updateFields = [
			'AUTO_MEMBER' => $value,
			'=DATE_UPDATE' => $helper->getCurrentDateTimeFunction(),
		];
		if (
			isset($params['ROLE'])
			&& in_array($params['ROLE'], UserToGroupTable::getRolesAll(), true)
		)
		{
			$updateFields['ROLE'] = $params['ROLE'];
		}
		\CSocNetUserToGroup::update($relationId, $updateFields);

		if (
			!$notyfy
			|| $userId <= 0
			|| $groupId <= 0
			|| $value !== 'Y'
		)
		{
			return;
		}

		self::notifyAutoMembership([
			'GROUP_ID' => $groupId,
			'USER_ID' => $userId,
			'RELATION_ID' => $relationId,
		]);

		self::addInfoToChat([
			'group_id' => $groupId,
			'user_id' => $userId,
			'action' => self::CHAT_ACTION_IN,
			'role' => ($params['ROLE'] ?? false),
		]);
	}

	private static function notifyAutoMembership($params): void
	{
		$userId = (int)($params['USER_ID'] ?? 0);
		$groupId = (int)($params['GROUP_ID'] ?? 0);
		$relationId = (int)($params['RELATION_ID'] ?? 0);

		if (
			$userId <= 0
			|| $groupId <= 0
			|| $relationId <= 0
			|| !Loader::includeModule('im')
		)
		{
			return;
		}
		$groupItem = Workgroup::getById($groupId);
		$groupFields = $groupItem->getFields();
		$groupUrlData = $groupItem->getGroupUrlData([
			'USER_ID' => $userId,
		]);

		$suffix = static::getChatMessageCodeSuffix($groupItem);
		$code = 'SOCIALNETWORK_ITEM_USERTOGROUP_AUTO_MEMBER_ADD_IM' . $suffix;

		if ($groupItem instanceof Collab)
		{
			$url = UrlManager::getCollabUrl($groupItem);
		}
		else
		{
			$url = $groupUrlData['DOMAIN'] . $groupUrlData['URL'];
		}

		$messageFields = [
			"MESSAGE_TYPE" => IM_MESSAGE_SYSTEM,
			"NOTIFY_TYPE" => IM_NOTIFY_SYSTEM,
			"FROM_USER_ID" => $groupFields["OWNER_ID"],
			"TO_USER_ID" => $userId,
			"NOTIFY_MODULE" => "socialnetwork",
			"NOTIFY_EVENT" => "invite_group",
			"NOTIFY_TAG" => "SOCNET|INVITE_GROUP|" . $userId . '|' . $relationId,
			"NOTIFY_MESSAGE" => fn (?string $languageId = null) => Loc::getMessage($code, [
					"#GROUP_NAME#" => "<a href=\"". $url . "\" class=\"bx-notifier-item-action\">" . htmlspecialcharsEx($groupFields["NAME"]) . '</a>',
				],
				$languageId
			),
			"NOTIFY_MESSAGE_OUT" => fn (?string $languageId = null) => Loc::getMessage("SOCIALNETWORK_ITEM_USERTOGROUP_AUTO_MEMBER_ADD_IM", [
						"#GROUP_NAME#" => htmlspecialcharsEx($groupFields["NAME"]),
					],
					$languageId
				) . ' (' . $groupUrlData['SERVER_NAME'] . $groupUrlData['URL'] . ')'
		];

		\CIMNotify::deleteBySubTag('SOCNET|REQUEST_GROUP|' . $userId . '|' . $groupId . '|' . $relationId);
		\CIMNotify::add($messageFields);
	}

	public static function onAfterUserAdd(&$fields): void
	{
		if (
			!isset($fields['ID'])
			|| $fields['ID'] <= 0
			|| (
				isset($fields['ACTIVE'])
				&& $fields['ACTIVE'] !== 'Y'
			)
			|| !self::checkUF()
		)
		{
			return;
		}

		$deparmentIdList = [];
		if (
			isset($fields['UF_DEPARTMENT'])
			&& is_array($fields['UF_DEPARTMENT'])
			&& (int)($fields['UF_DEPARTMENT'][0] ?? 0) > 0
		)
		{
			$deparmentIdList = $fields['UF_DEPARTMENT'];
		}

		if (Loader::includeModule('intranet'))
		{
			$deparmentIdList = array_merge($deparmentIdList, \CIntranetUtils::getSubordinateDepartments($fields['ID'], false));
		}

		$deparmentIdList = array_unique($deparmentIdList);

		if (
			empty($deparmentIdList)
			|| !ModuleManager::isModuleInstalled('intranet')
			|| !Loader::includeModule('iblock')
		)
		{
			return;
		}

		$groupList = self::getConnectedGroups($deparmentIdList);
		if (empty($groupList))
		{
			return;
		}

		foreach($groupList as $groupId)
		{
			self::addRelationAutoMembership([
				'USER_ID' => $fields['ID'],
				'GROUP_ID' => $groupId,
				'NOTIFY' => 'N',
			]);
		}
	}

	public static function onAfterUserUpdate(&$userFields): void
	{
		if (!self::checkUF())
		{
			return;
		}

		if (
			(int)$userFields['ID'] <= 0
			|| !isset($userFields['UF_DEPARTMENT'])
			|| !ModuleManager::isModuleInstalled('intranet')
			|| !Loader::includeModule('iblock')
		)
		{
			return;
		}

		$oldGroupList = [];
		$oldGroupAutoList = [];
		$newGroupList = [];

		$res = UserToGroupTable::getList([
			'filter' => [
				'USER_ID' => (int)$userFields['ID']
			],
			'select' => [ 'GROUP_ID', 'AUTO_MEMBER' ]
		]);

		while($relation = $res->fetch())
		{
			$oldGroupList[] = $relation['GROUP_ID'];
			if ($relation['AUTO_MEMBER'] === 'Y')
			{
				$oldGroupAutoList[] = $relation['GROUP_ID'];
			}
		}
		$oldGroupList = array_unique($oldGroupList);
		$oldGroupAutoList = array_unique($oldGroupAutoList);

		if (
			!empty($userFields['UF_DEPARTMENT'])
			&& is_array($userFields['UF_DEPARTMENT'])
		)
		{
			$userFields['UF_DEPARTMENT'] = array_values($userFields['UF_DEPARTMENT']);
		}

		$departmentList = (
			!is_array($userFields['UF_DEPARTMENT'])
			|| empty($userFields['UF_DEPARTMENT'])
			|| (int)$userFields['UF_DEPARTMENT'][0] <= 0
				? []
				: $userFields['UF_DEPARTMENT']
		);

		if (Loader::includeModule('intranet'))
		{
			$departmentList = array_merge($departmentList, \CIntranetUtils::getSubordinateDepartments($userFields['ID'], false));
		}
		$departmentList = array_unique($departmentList);

		if (!empty($departmentList))
		{
			$newGroupList = self::getConnectedGroups($departmentList);
		}
		$groupListPlus = array_diff($newGroupList, $oldGroupList);
		$groupListMinus = array_diff($oldGroupAutoList, $newGroupList);
		$groupListMinus = array_diff($groupListMinus, $groupListPlus);

		if (!empty($groupListMinus))
		{
			$res = UserToGroupTable::getList([
				'filter' => [
					'=USER_ID' => (int)$userFields['ID'],
					'@GROUP_ID' => $groupListMinus,
					'@ROLE' => [ UserToGroupTable::ROLE_OWNER, UserToGroupTable::ROLE_MODERATOR, UserToGroupTable::ROLE_USER ],
					'AUTO_MEMBER' => 'Y'
				],
				'select' => [ 'ID' ],
			]);
			while($relation = $res->fetch())
			{
				\CSocNetUserToGroup::delete($relation['ID']);
			}
		}

		$changeList = $addList = $noChangeList = [];
		if (!empty($groupListPlus))
		{
			$res = UserToGroupTable::getList([
				'filter' => [
					'=USER_ID' => (int)$userFields["ID"],
					'@GROUP_ID' => $groupListPlus,
					'@ROLE' => [ UserToGroupTable::ROLE_OWNER, UserToGroupTable::ROLE_MODERATOR, UserToGroupTable::ROLE_USER ],
				],
				'select' => [ 'ID', 'GROUP_ID', 'AUTO_MEMBER' ],
			]);

			while ($relation = $res->fetch())
			{
				if (
					$relation['AUTO_MEMBER'] === 'Y'
					|| $relation['ROLE'] === UserToGroupTable::ROLE_OWNER
				)
				{
					$noChangeList[] = $relation['GROUP_ID'];
				}
				else // UserToGroupTable::ROLE_MODERATOR, UserToGroupTable::ROLE_USER, AUTO_MEMBER = 'N'
				{
					$noChangeList[] = $relation['GROUP_ID'];
					self::changeRelationAutoMembership([
						'RELATION_ID' => (int)$relation['ID'],
						'USER_ID' => (int)$userFields["ID"],
						'GROUP_ID' => (int)$relation['GROUP_ID'],
						'ROLE' => $relation['ROLE'],
						'VALUE' => 'Y',
						'NOTIFY' => 'N',
					]);
				}
			}

			$groupListPlus = array_diff($groupListPlus, $noChangeList);
		}

		if (!empty($groupListPlus))
		{
			$res = UserToGroupTable::getList([
				'filter' => [
					'=USER_ID' => (int)$userFields['ID'],
					'@GROUP_ID' => $groupListPlus,
					'@ROLE' => [ UserToGroupTable::ROLE_REQUEST, UserToGroupTable::ROLE_BAN ],
					'AUTO_MEMBER' => 'N',
				],
				'select' => [ 'ID', 'USER_ID', 'GROUP_ID' ],
			]);

			while ($relation = $res->fetch())
			{
				$changeList[] = (int)$relation['GROUP_ID'];
				self::changeRelationAutoMembership([
					'RELATION_ID' => (int)$relation['ID'],
					'USER_ID' => (int)$relation['USER_ID'],
					'GROUP_ID' => (int)$relation['GROUP_ID'],
					'ROLE' => UserToGroupTable::ROLE_USER,
					'VALUE' => 'Y',
				]);
			}
			$addList = array_diff($groupListPlus, $changeList);
		}

		foreach ($addList as $addGroupId)
		{
			self::addRelationAutoMembership([
				'USER_ID' => (int)$userFields['ID'],
				'GROUP_ID' => $addGroupId,
				'ROLE' => UserToGroupTable::ROLE_USER,
				'VALUE' => 'Y',
			]);
		}
	}

	public static function getConnectedGroups($departmentList): array
	{
		static $structureIBlockId = false;
		static $departmentChainCache = [];

		$result = [];

		if ($structureIBlockId === false)
		{
			$structureIBlockId = (int)Option::get('intranet', 'iblock_structure', 0);
		}

		if ((int)$structureIBlockId <= 0)
		{
			return $result;
		}

		$userDepartmentList = [];

		foreach($departmentList as $departmentId)
		{
			$departmentChain = [];
			if (isset($departmentChainCache[$departmentId]))
			{
				$departmentChain = $departmentChainCache[$departmentId];
			}
			else
			{
				$res = \CIBlockSection::getNavChain($structureIBlockId, $departmentId, [ 'ID' ]);
				while ($section = $res->fetch())
				{
					if ((int)$section['ID'] > 0)
					{
						$departmentChain[] = (int)$section['ID'];
					}
				}
				$departmentChainCache[$departmentId] = $departmentChain;
			}
			$userDepartmentList = array_merge($userDepartmentList, $departmentChain);
		}

		$userDepartmentList = array_unique($userDepartmentList);

		if (!empty($userDepartmentList))
		{
			$res = WorkgroupTable::getList([
				'filter' => [
					'@UF_SG_DEPT' => $userDepartmentList,
				],
				'select' => [ 'ID' ],
			]);
			while ($group = $res->fetch())
			{
				if ((int)$group['ID'] > 0)
				{
					$result[] = (int)$group['ID'];
				}
			}
		}

		return array_unique($result);
	}

	private static function checkUF(): bool
	{
		$res = \CUserTypeEntity::getList([], [
			'ENTITY_ID' => 'SONET_GROUP',
			'FIELD_NAME' => 'UF_SG_DEPT'
		]);
		return ($res && ($res->fetch()));
	}

	public static function addInfoToChat($params = [])
	{
		if (
			!is_array($params)
			|| !isset($params['group_id'], $params['user_id'], $params['action'])
			|| (int)$params['group_id'] <= 0
			|| (int)$params['user_id'] <= 0
			|| !Loader::includeModule('im')
		)
		{
			return false;
		}

		$groupId = (int)$params['group_id'];
		$userId = (int)$params['user_id'];
		$action = (string)$params['action'];

		$group = GroupRegistry::getInstance()->get($groupId);

		if ($group === null)
		{
			return false;
		}

		if (!$group->isCollab() && !Integration\Im\Chat\Workgroup::getUseChat())
		{
			return false;
		}

		if ($group->isCollab() && ActionType::isValid($action))
		{
			$factory = ActionMessageFactory::getInstance();
			$message = $factory->getActionMessage(ActionType::from($action), $groupId, $userId);

			$recipientIds = (array)($params['recipientIds'] ?? []);

			return $message->send($recipientIds, $params);
		}

		if (!in_array($action, self::getChatActionList(), true))
		{
			return false;
		}

		$role = ($params['role'] ?? false);

		$sendMessage = (
			!isset($params['sendMessage'])
			|| $params['sendMessage']
		);

		$chatData = Integration\Im\Chat\Workgroup::getChatData([
			'group_id' => $groupId,
			'skipAvailabilityCheck' => true,
		]);

		if (
			empty($chatData)
			|| empty($chatData[$groupId])
			|| (int)$chatData[$groupId] <= 0
		)
		{
			return false;
		}

		$res = \CUser::getById($userId);
		$user = $res->fetch();

		if (
			empty($user)
			|| (
				isset($user['ACTIVE'])
				&& $user['ACTIVE'] === 'N'
			)
		)
		{
			return false;
		}

		$suffix = static::getChatMessageCodeSuffix($group);

		$userName = \CUser::formatName(\CSite::getNameFormat(), $user, true, false);
		switch($user['PERSONAL_GENDER'])
		{
			case "M":
				$genderSuffix = '_M';
				break;
			case "F":
				$genderSuffix = '_F';
				break;
			default:
				$genderSuffix = '';
		}

		$chatId = $chatData[$groupId];
		$chat = new \CIMChat(0);

		switch ($params['action'])
		{
			case self::CHAT_ACTION_IN:
				if ($chat->addUser($chatId, $userId, false, true, true))
				{
					if ($role === UserToGroupTable::ROLE_USER)
					{
						\Bitrix\Im\Chat::mute($chatId, true, $userId);
					}

					$chatMessage = str_replace('#USER_NAME#', $userName, Loc::getMessage('SOCIALNETWORK_ITEM_USERTOGROUP_CHAT_USER_ADD' . $suffix . $genderSuffix));
				}
				else
				{
					$sendMessage = false;
				}
				break;
			case self::CHAT_ACTION_OUT:
				if ($chat->deleteUser($chatId, $userId, false, true))
				{
					$chatMessage = str_replace('#USER_NAME#', $userName, Loc::getMessage('SOCIALNETWORK_ITEM_USERTOGROUP_CHAT_USER_DELETE' . $suffix . $genderSuffix));
				}
				else
				{
					$sendMessage = false;
				}
				break;

			default:
				$chatMessage = '';
				$sendMessage = false;
		}

		if ($sendMessage)
		{
			$chatMessageFields = [
				"MESSAGE" => $chatMessage,
				"SYSTEM" => "Y",
				"INCREMENT_COUNTER" => "N",
				"PUSH" => "N"
			];

			$availableChatData = Integration\Im\Chat\Workgroup::getChatData([
				'group_id' => $groupId,
			]);

			if (
				!empty($availableChatData)
				&& !empty($availableChatData[$groupId])
				&& (int)$availableChatData[$groupId] > 0
			)
			{
				return \CIMChat::addMessage(array_merge(
					$chatMessageFields, [
						'TO_CHAT_ID' => $chatId,
					]
				));
			}
		}
		else
		{
			return true;
		}

		return false;
	}

	private static function getChatMessageCodeSuffix(Workgroup $group): string
	{
		return match (true) {
			$group->isProject() => '_PROJECT',
			$group->isCollab() => '_COLLAB',
			default => '',
		};
	}

	private static function getChatActionList(): array
	{
		return [self::CHAT_ACTION_IN, self::CHAT_ACTION_OUT];
	}

	public static function addModerators($params = []): bool
	{
		global $USER;

		$result = false;

		if (
			!is_array($params)
			|| !isset($params['group_id'], $params['user_id'])
 			|| (int)$params['group_id'] <= 0
			|| empty($params['user_id'])
		)
		{
			return $result;
		}

		$groupId = (int)$params['group_id'];
		$userIdList = (
			is_array($params['user_id'])
				? $params['user_id']
				: [ $params['user_id'] ]
		);
		$currentUserId = (
			isset($params['current_user_id'])
			&& (int)$params['current_user_id'] > 0
				? (int)$params['current_user_id']
				: (
					is_object($USER)
					&& $USER->isAuthorized()
						? $USER->getId()
						: false
				)
		);

		if (!$currentUserId)
		{
			return $result;
		}

		$ownerRelationIdList = [];
		$memberRelationIdList = [];
		$otherRelationIdList = [];

		$resRelation = UserToGroupTable::getList([
			'filter' => [
				'GROUP_ID' => $groupId,
				'@USER_ID' => $userIdList
			],
			'select' => [ 'ID', 'USER_ID', 'ROLE' ],
		]);

		while ($relation = $resRelation->fetch())
		{
			if ($relation['ROLE'] === UserToGroupTable::ROLE_USER)
			{
				$memberRelationIdList[$relation['USER_ID']] = $relation['ID'];
			}
			elseif ($relation['ROLE'] === UserToGroupTable::ROLE_OWNER)
			{
				$ownerRelationIdList[$relation['USER_ID']] = $relation['ID'];
			}
			else // ban, request
			{
				$otherRelationIdList[$relation['USER_ID']] = $relation['ID'];
			}
		}

		if (!empty($memberRelationIdList))
		{
			\CSocNetUserToGroup::transferMember2Moderator($currentUserId, $groupId, $memberRelationIdList);
		}

		foreach ($userIdList as $userId)
		{
			if (
				!array_key_exists($userId, $memberRelationIdList)
				&& !array_key_exists($userId, $ownerRelationIdList)
			)
			{
				if (array_key_exists($userId, $otherRelationIdList))
				{
					$relationId = \CSocNetUserToGroup::update($otherRelationIdList[$userId], [
						'ROLE' => UserToGroupTable::ROLE_MODERATOR,
						'=DATE_UPDATE' => \CDatabase::CurrentTimeFunction(),
					]);
				}
				else
				{
					$relationId = \CSocNetUserToGroup::add([
						'USER_ID' => $userId,
						'GROUP_ID' => $groupId,
						'ROLE' => UserToGroupTable::ROLE_MODERATOR,
						'=DATE_CREATE' => \CDatabase::CurrentTimeFunction(),
						'=DATE_UPDATE' => \CDatabase::CurrentTimeFunction(),
						'MESSAGE' => '',
						'INITIATED_BY_TYPE' => UserToGroupTable::INITIATED_BY_GROUP,
						'INITIATED_BY_USER_ID' => $currentUserId,
						'SEND_MAIL' => 'N',
					]);
				}

				if ($relationId)
				{
					\CSocNetUserToGroup::notifyModeratorAdded([
						'userId' => $currentUserId,
						'groupId' => $groupId,
						'relationId' => $relationId
					]);
				}
			}
		}

		return true;
	}

}

Youez - 2016 - github.com/yon3zu
LinuXploit