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/classes/general/ |
Upload File : |
<?php use Bitrix\Main\Application; use Bitrix\Main\Config\Option; use Bitrix\Main\Event; use Bitrix\Main\ModuleManager; use Bitrix\Main\Text\Emoji; use Bitrix\Main; use Bitrix\Main\Type\Collection; use Bitrix\Socialnetwork\Collab\Integration\IM\ActionType; use Bitrix\Socialnetwork\Collab\Integration\IM\ActionMessageFactory; use Bitrix\Socialnetwork\Collab\Registry\CollabRegistry; use Bitrix\Socialnetwork\Helper\Path; use Bitrix\Socialnetwork\Item\Workgroup; use Bitrix\Socialnetwork\UserToGroupTable; use Bitrix\Socialnetwork\Item\UserToGroup; use Bitrix\Socialnetwork\Integration; use Bitrix\Main\Localization\Loc; use Bitrix\Main\Loader; use Bitrix\Socialnetwork\WorkgroupTable; use Bitrix\Socialnetwork\Internals\Counter; use Bitrix\Socialnetwork\Internals\EventService; Loc::loadMessages(__FILE__); class CAllSocNetUserToGroup { protected static $roleCache = array(); protected const EVENTS_JOB_PRIORITY = -1; protected const LOCK_TIMEOUT = 15; /***************************************/ /******** DATA MODIFICATION **********/ /***************************************/ public static function CheckFields($ACTION, &$relationFields, $id = 0): bool { global $APPLICATION, $DB, $arSocNetAllowedRolesForUserInGroup, $arSocNetAllowedInitiatedByType; if ($ACTION !== "ADD" && (int)$id <= 0) { $APPLICATION->ThrowException("System error 870164", "ERROR"); return false; } if ( (isset($relationFields['USER_ID']) || $ACTION === "ADD") && (int)$relationFields["USER_ID"] <= 0 ) { $APPLICATION->ThrowException(Loc::getMessage('SONET_UG_EMPTY_USER_ID'), 'EMPTY_USER_ID'); return false; } if (isset($relationFields['USER_ID'])) { $res = CUser::getList( 'ID', 'ASC', ['ID_EQUAL_EXACT' => $relationFields["USER_ID"]], ['FIELDS' => ['ID']], ); if (!$res->fetch()) { $APPLICATION->ThrowException(Loc::getMessage('SONET_UG_ERROR_NO_USER_ID'), 'ERROR_NO_USER_ID'); return false; } } if ( (isset($relationFields['GROUP_ID']) || $ACTION === "ADD") && (int)$relationFields["GROUP_ID"] <= 0 ) { $APPLICATION->ThrowException(Loc::getMessage('SONET_UG_EMPTY_GROUP_ID'), 'EMPTY_GROUP_ID'); return false; } if ( isset($relationFields["GROUP_ID"]) && !CSocNetGroup::getById($relationFields["GROUP_ID"]) ) { $APPLICATION->ThrowException(Loc::getMessage('SONET_UG_ERROR_NO_GROUP_ID'), 'ERROR_NO_GROUP_ID'); return false; } if ( (isset($relationFields["ROLE"]) || $ACTION === "ADD") && $relationFields["ROLE"] === '' ) { $APPLICATION->ThrowException(Loc::getMessage('SONET_UG_EMPTY_ROLE'), 'EMPTY_ROLE'); return false; } if ( isset($relationFields["ROLE"]) && !in_array($relationFields["ROLE"], $arSocNetAllowedRolesForUserInGroup, true) ) { $APPLICATION->ThrowException(str_replace( "#ID#", $relationFields["ROLE"], Loc::getMessage('SONET_UG_ERROR_NO_ROLE') ), 'ERROR_NO_ROLE'); return false; } if ( (isset($relationFields["INITIATED_BY_TYPE"]) || $ACTION === "ADD") && (string)$relationFields["INITIATED_BY_TYPE"] === '' ) { $APPLICATION->ThrowException(Loc::getMessage('SONET_UG_EMPTY_INITIATED_BY_TYPE'), 'EMPTY_INITIATED_BY_TYPE'); return false; } if ( isset($relationFields["INITIATED_BY_TYPE"]) && !in_array($relationFields["INITIATED_BY_TYPE"], $arSocNetAllowedInitiatedByType, true) ) { $APPLICATION->ThrowException(str_replace( '#ID#', $relationFields["INITIATED_BY_TYPE"], Loc::getMessage('SONET_UG_ERROR_NO_INITIATED_BY_TYPE') ), 'ERROR_NO_INITIATED_BY_TYPE'); return false; } if ( (isset($relationFields['INITIATED_BY_USER_ID']) || $ACTION === "ADD") && (int)$relationFields['INITIATED_BY_USER_ID'] <= 0 ) { $APPLICATION->ThrowException( Loc::getMessage('SONET_UG_EMPTY_INITIATED_BY_USER_ID'), 'EMPTY_INITIATED_BY_USER_ID' ); return false; } if (isset($relationFields["INITIATED_BY_USER_ID"])) { $res = CUser::GetByID($relationFields["INITIATED_BY_USER_ID"]); if (!$res->fetch()) { $APPLICATION->ThrowException( Loc::getMessage('SONET_UG_ERROR_NO_INITIATED_BY_USER_ID'), 'ERROR_NO_INITIATED_BY_USER_ID' ); return false; } } if ( isset($relationFields['DATE_CREATE']) && !$DB->IsDate($relationFields['DATE_CREATE'], false, LANG, 'FULL') ) { $APPLICATION->ThrowException(Loc::getMessage('SONET_UG_EMPTY_DATE_CREATE'), 'EMPTY_DATE_CREATE'); return false; } if ( isset($relationFields['DATE_UPDATE']) && !$DB->IsDate($relationFields['DATE_UPDATE'], false, LANG, 'FULL') ) { $APPLICATION->ThrowException(Loc::getMessage('SONET_UG_EMPTY_DATE_UPDATE'), 'EMPTY_DATE_UPDATE'); return false; } if ( isset($relationFields['DATE_LAST_VIEW']) && !$DB->IsDate($relationFields['DATE_LAST_VIEW'], false, LANG, 'FULL') ) { $APPLICATION->ThrowException(Loc::getMessage('SONET_UG_EMPTY_DATE_LAST_VIEW'), 'EMPTY_DATE_LAST_VIEW'); return false; } if ( ( isset($relationFields["SEND_MAIL"]) && $relationFields["SEND_MAIL"] !== "N" ) || !isset($relationFields['SEND_MAIL']) ) { $relationFields["SEND_MAIL"] = "Y"; } return true; } public static function Delete( $id, $sendExclude = false, bool $skipChatMessage = false, bool $skipStatistics = false, bool $delayEvents = false ) { global $APPLICATION, $DB, $USER, $CACHE_MANAGER; if (!CSocNetGroup::__ValidateID($id)) { return false; } $id = (int)$id; $relationFields = CSocNetUserToGroup::GetByID($id); if (!$relationFields) { $APPLICATION->ThrowException(Loc::getMessage('SONET_NO_USER2GROUP'), 'ERROR_NO_USER2GROUP'); return false; } $res = GetModuleEvents("socialnetwork", "OnBeforeSocNetUserToGroupDelete"); while ($eventFields = $res->Fetch()) { if (ExecuteModuleEventEx($eventFields, array($id)) === false) { return false; } } $events = GetModuleEvents("socialnetwork", "OnSocNetUserToGroupDelete"); while ($eventFields = $events->Fetch()) { if ($delayEvents) { static::delayJob(static fn () => ExecuteModuleEventEx($eventFields, [ $id, $relationFields ])); } else { ExecuteModuleEventEx($eventFields, [ $id, $relationFields ]); } } EventService\Service::addEvent(EventService\EventDictionary::EVENT_WORKGROUP_USER_DELETE, [ 'GROUP_ID' => $relationFields['GROUP_ID'], 'USER_ID' => $relationFields['USER_ID'], 'ROLE' => $relationFields['ROLE'] ?? null, 'INITIATED_BY_TYPE' => $relationFields['INITIATED_BY_TYPE'] ?? null, ]); EventService\Service::addEvent(EventService\EventDictionary::EVENT_SPACE_USER_ROLE_CHANGE, [ 'GROUP_ID' => $relationFields['GROUP_ID'], 'USER_ID' => $relationFields['USER_ID'], ]); if (Loader::includeModule('im')) { CIMNotify::DeleteByTag("SOCNET|INVITE_GROUP|" . (int)$relationFields['USER_ID'] . "|" . (int)$id); } $bSuccess = $DB->Query("DELETE FROM b_sonet_user2group WHERE ID = ".$id."", true); if (!$skipStatistics) { CSocNetGroup::SetStat($relationFields["GROUP_ID"]); } CSocNetSearch::OnUserRelationsChange($relationFields["USER_ID"]); $event = new Event('socialnetwork', 'OnAfterSocNetUserToGroupDelete', $relationFields); if ($delayEvents) { static::delayJob(static fn () => $event->send()); } else { $event->send(); } $roleCacheKey = $relationFields['USER_ID'] . '_' . $relationFields['GROUP_ID']; if (isset(self::$roleCache[$roleCacheKey])) { unset(self::$roleCache[$roleCacheKey]); } if ($bSuccess && defined("BX_COMP_MANAGED_CACHE")) { $CACHE_MANAGER->ClearByTag("sonet_user2group_G".$relationFields["GROUP_ID"]); $CACHE_MANAGER->ClearByTag("sonet_user2group_U".$relationFields["USER_ID"]); $CACHE_MANAGER->ClearByTag("sonet_user2group"); } if ( $bSuccess && in_array($relationFields['ROLE'], [ UserToGroupTable::ROLE_MODERATOR, UserToGroupTable::ROLE_USER, ], true) ) { $chatNotificationResult = false; if (!$skipChatMessage && Loader::includeModule('im')) { $chatNotificationResult = UserToGroup::addInfoToChat([ 'group_id' => $relationFields["GROUP_ID"], 'user_id' => $relationFields["USER_ID"], 'action' => UserToGroup::CHAT_ACTION_OUT, 'sendMessage' => $sendExclude, ]); if ($sendExclude) { $arMessageFields = [ "TO_USER_ID" => $relationFields["USER_ID"], "FROM_USER_ID" => 0, "NOTIFY_TYPE" => IM_NOTIFY_SYSTEM, "NOTIFY_MODULE" => "socialnetwork", "NOTIFY_EVENT" => "invite_group", "NOTIFY_TAG" => "SOCNET|INVITE_GROUP|" . (int)$relationFields["USER_ID"] . "|" . (int)$relationFields["ID"], "NOTIFY_MESSAGE" => fn (?string $languageId = null) => Loc::getMessage( 'SONET_UG_EXCLUDE_MESSAGE', ["#NAME#" => $relationFields["GROUP_NAME"]], $languageId ), ]; CIMNotify::Add($arMessageFields); } } if ( $sendExclude && !$chatNotificationResult ) { CSocNetUserToGroup::notifyImToModerators([ "TYPE" => "exclude", "RELATION_ID" => $relationFields["ID"], "USER_ID" => $relationFields["USER_ID"], "GROUP_ID" => $relationFields["GROUP_ID"], "GROUP_NAME" => $relationFields["GROUP_NAME"], "EXCLUDE_USERS" => array($USER->getId()), ]); } } Counter\CounterService::addEvent(Counter\Event\EventDictionary::EVENT_WORKGROUP_USER_DELETE, [ 'GROUP_ID' => (int)$relationFields['GROUP_ID'], 'USER_ID' => (int)$relationFields['USER_ID'], 'ROLE' => $relationFields['ROLE'], 'INITIATED_BY_TYPE' => ($relationFields['INITIATED_BY_TYPE']), 'RELATION_ID' => (int)$relationFields['ID'], ]); return $bSuccess; } public static function DeleteNoDemand($userId): bool { global $DB; if (!CSocNetGroup::__ValidateID($userId)) { return false; } $userId = (int)$userId; $bSuccess = True; $groupIdList = []; $res = CSocNetUserToGroup::GetList(array(), array("USER_ID" => $userId), false, false, array("GROUP_ID")); while ($relationFields = $res->fetch()) { $groupIdList[] = (int)$relationFields["GROUP_ID"]; } $DB->Query("DELETE FROM b_sonet_user2group WHERE USER_ID = ".$userId."", true); foreach ($groupIdList as $groupId) { CSocNetGroup::SetStat($groupId); } self::$roleCache = array(); CSocNetUserToGroup::__SpeedFileDelete($userId); CSocNetSearch::OnUserRelationsChange($userId); return $bSuccess; } /***************************************/ /********** DATA SELECTION ***********/ /***************************************/ public static function GetById($id) { if (!CSocNetGroup::__ValidateID($id)) { return false; } $id = (int)$id; $res = CSocNetUserToGroup::GetList( [], [ 'ID' => $id ], false, false, [ 'ID', 'ROLE', 'DATE_CREATE', 'DATE_UPDATE', 'INITIATED_BY_TYPE', 'INITIATED_BY_USER_ID', 'MESSAGE', 'USER_ID', 'GROUP_ID', 'GROUP_VISIBLE', 'GROUP_NAME', ] ); if ($relationFields = $res->fetch()) { if (!empty($relationFields['GROUP_NAME'])) { $relationFields['GROUP_NAME'] = Emoji::decode(htmlspecialcharsEx($relationFields['GROUP_NAME'])); } return $relationFields; } return false; } public static function GetGroupUsers(int $groupId): array { return UserToGroupTable::query() ->setSelect([ 'USER_ID', 'GROUP_ID', 'ROLE', 'AUTO_MEMBER' ]) ->where('GROUP_ID', $groupId) ->fetchAll() ; } public static function AddUsersToGroup(int $groupId, array $userIds): Main\Result { if (empty($userIds)) { return (new Main\Result())->addError(new Main\Error('$userIds is empty')); } $users = []; foreach($userIds as $userId) { $users[] = [ 'USER_ID' => $userId, 'GROUP_ID' => $groupId, 'ROLE' => UserToGroupTable::ROLE_USER, 'DATE_CREATE' => new Main\Type\DateTime(), 'DATE_UPDATE' => new Main\Type\DateTime(), 'INITIATED_BY_USER_ID' => $userId, ]; } return UserToGroupTable::addMulti($users, true); } public static function addUniqueUsersToGroup(int $groupId, array $userIds): void { $connection = Application::getConnection(); $lockName = 'socnet_update_group_users_lock_' . $groupId; if (!$connection->lock($lockName, static::LOCK_TIMEOUT)) { return; } try { $oldUsers = self::GetGroupUsers($groupId); $oldUserIds = array_map('intval', array_column($oldUsers, 'USER_ID')); $newUserIds = array_map('intval', $userIds); $usersToAdd = array_diff($newUserIds, $oldUserIds); Collection::normalizeArrayValuesByInt($usersToAdd); self::AddUsersToGroup($groupId, $usersToAdd); } catch (Throwable) { } finally { $connection->unlock($lockName); } } /***************************************/ /********** COMMON METHODS ***********/ /***************************************/ public static function GetUserRole($userId, $groupId, $extendedReturn = false) { $userId = (int)$userId; if ($userId <= 0) { return false; } // compatibility? if (isset($_REQUEST['arSocNetUserInRoleCache'])) { self::$roleCache = []; } if (is_array($groupId)) { $result = false; $groupIdListToGet = []; foreach ($groupId as $TmpGroupID) { $cacheKey = $userId . '_' . $TmpGroupID; if (!isset(self::$roleCache[$cacheKey])) { $groupIdListToGet[] = $TmpGroupID; } } if (count($groupIdListToGet) > 0) { $res = CSocNetUserToGroup::getList( [], [ 'USER_ID' => $userId, 'GROUP_ID' => $groupIdListToGet, ], false, false, [ 'GROUP_ID', 'ROLE', 'AUTO_MEMBER' ] ); $arRolesFromDB = []; while ($relationFields = $res->fetch()) { $arRolesFromDB[$relationFields["GROUP_ID"]] = [ "ROLE" => $relationFields["ROLE"], "AUTO_MEMBER" => $relationFields["AUTO_MEMBER"], ]; } foreach ($groupIdListToGet as $TmpGroupID) { self::$roleCache[$userId."_".$TmpGroupID] = ( array_key_exists($TmpGroupID, $arRolesFromDB) ? [ "ROLE" => $arRolesFromDB[$TmpGroupID]["ROLE"], "AUTO_MEMBER" => $arRolesFromDB[$TmpGroupID]["AUTO_MEMBER"], ] : array( "ROLE" => false, "AUTO_MEMBER" => "N" ) ); } } foreach ($groupId as $currentGroupId) { if ($result === false) { $result = []; } $result[$currentGroupId] = ( $extendedReturn ? self::$roleCache[$userId . '_' . $currentGroupId] : self::$roleCache[$userId . '_' . $currentGroupId]['ROLE'] ); } return $result; } $groupId = (int)$groupId; if ($groupId <= 0) { return false; } if (!array_key_exists($userId."_".$groupId, self::$roleCache)) { $res = CSocNetUserToGroup::GetList( array(), array("USER_ID" => $userId, "GROUP_ID" => $groupId), false, false, array("ROLE", "AUTO_MEMBER") ); if ($relationFields = $res->Fetch()) { self::$roleCache[$userId."_".$groupId] = array( "ROLE" => $relationFields["ROLE"], "AUTO_MEMBER" => $relationFields["AUTO_MEMBER"] ); } else { self::$roleCache[$userId."_".$groupId] = array( "ROLE" => false, "AUTO_MEMBER" => false ); } } return ( $extendedReturn ? self::$roleCache[$userId."_".$groupId] : self::$roleCache[$userId."_".$groupId]["ROLE"] ); } /***************************************/ /********** SEND EVENTS **************/ /***************************************/ public static function SendEvent($userGroupID, $mailTemplate = "SONET_INVITE_GROUP"): bool { $userGroupID = (int)$userGroupID; if ($userGroupID <= 0) { return false; } $dbRelation = CSocNetUserToGroup::GetList( [], [ 'ID' => $userGroupID ], false, false, [ 'ID', 'ROLE', 'DATE_CREATE', 'MESSAGE', 'INITIATED_BY_TYPE', 'INITIATED_BY_USER_ID', 'USER_ID', 'USER_NAME', 'USER_LAST_NAME', 'USER_EMAIL', 'USER_LID', 'GROUP_ID', 'GROUP_NAME', ] ); $arRelation = $dbRelation->Fetch(); if (!$arRelation) { return false; } $arUserGroup = array(); if (Loader::includeModule('extranet')) { $arUserGroup = CUser::GetUserGroup($arRelation["USER_ID"]); } $bExtranetInstalled = ModuleManager::isModuleInstalled('extranet'); $siteId = false; $rsGroupSite = CSocNetGroup::GetSite($arRelation["GROUP_ID"]); while ($arGroupSite = $rsGroupSite->Fetch()) { if ($bExtranetInstalled) { if ( ( CExtranet::IsExtranetSite($arGroupSite["LID"]) && in_array(CExtranet::GetExtranetUserGroupID(), $arUserGroup) ) || ( !CExtranet::IsExtranetSite($arGroupSite["LID"]) && !in_array(CExtranet::GetExtranetUserGroupID(), $arUserGroup) ) ) { $siteId = $arGroupSite["LID"]; break; } } else { $siteId = $arGroupSite["LID"]; break; } } if (empty($siteId)) { return false; } $requestsPagePath = str_replace( "#USER_ID#", $arRelation["USER_ID"], Option::get( "socialnetwork", "user_request_page", ( ModuleManager::isModuleInstalled('intranet') ? "/company/personal/user/#USER_ID#/requests/" : "/club/user/#USER_ID#/requests/" ), $siteId ) ); $arUserInitiatedForEmail = array("NAME"=>"", "LAST_NAME"=>""); if ((int)$arRelation["INITIATED_BY_USER_ID"] > 0): $dbUserInitiated = CUser::GetList( "id", "desc", array("ID" => $arRelation["INITIATED_BY_USER_ID"]) ); if ($arUserInitiated = $dbUserInitiated->Fetch()) { $arUserInitiatedForEmail = [ 'NAME' => $arUserInitiated['NAME'], 'LAST_NAME' => $arUserInitiated['LAST_NAME'], ]; } endif; $arFields = array( "RELATION_ID" => $userGroupID, "URL" => $requestsPagePath, "GROUP_ID" => $arRelation["GROUP_ID"], "USER_ID" => $arRelation["USER_ID"], "GROUP_NAME" => Emoji::decode($arRelation["GROUP_NAME"]), "USER_NAME" => $arRelation["USER_NAME"], "USER_LAST_NAME" => $arRelation["USER_LAST_NAME"], "USER_EMAIL" => $arRelation["USER_EMAIL"], "INITIATED_USER_NAME" => $arUserInitiatedForEmail["NAME"], "INITIATED_USER_LAST_NAME" => $arUserInitiatedForEmail["LAST_NAME"], "MESSAGE" => $arRelation["MESSAGE"] ); CEvent::Send($mailTemplate, $siteId, $arFields, "N"); return true; } /***************************************/ /************ ACTIONS ****************/ /***************************************/ public static function SendRequestToBeMember($userId, $groupId, $message, $requestConfirmUrl = "", $autoSubscribe = true): bool { global $APPLICATION; $userId = (int)$userId; if ($userId <= 0) { $APPLICATION->ThrowException(Loc::getMessage('SONET_UR_EMPTY_USERID'), 'ERROR_USERID'); return false; } $groupId = (int)$groupId; if ($groupId <= 0) { $APPLICATION->ThrowException(Loc::getMessage('SONET_UR_EMPTY_GROUPID'), 'ERROR_GROUPID'); return false; } $groupFields = WorkgroupTable::getList([ 'select' => [ 'ACTIVE', 'OPENED', 'NAME', 'INITIATE_PERMS', 'SITE_ID', ], 'filter' => ['ID' => $groupId], ])->fetch(); if ( !$groupFields || !is_array($groupFields) || $groupFields["ACTIVE"] !== "Y" /* || $arGroup["VISIBLE"] != "Y"*/) { $APPLICATION->ThrowException(Loc::getMessage('SONET_UG_ERROR_NO_GROUP_ID'), 'ERROR_NO_GROUP'); return false; } $relationFields = [ "USER_ID" => $userId, "GROUP_ID" => $groupId, "ROLE" => UserToGroupTable::ROLE_REQUEST, "=DATE_CREATE" => CDatabase::CurrentTimeFunction(), "=DATE_UPDATE" => CDatabase::CurrentTimeFunction(), "MESSAGE" => $message, "INITIATED_BY_TYPE" => SONET_INITIATED_BY_USER, "INITIATED_BY_USER_ID" => $userId ]; if ($groupFields["OPENED"] === "Y") { $relationFields["ROLE"] = UserToGroupTable::ROLE_USER; } $ID = CSocNetUserToGroup::Add($relationFields); if (!$ID) { $errorMessage = ""; if ($e = $APPLICATION->GetException()) { $errorMessage = $e->GetString(); } if ($errorMessage === '') { $errorMessage = Loc::getMessage("SONET_UR_ERROR_CREATE_USER2GROUP"); } $APPLICATION->ThrowException($errorMessage, "ERROR_CREATE_USER2GROUP"); return false; } \Bitrix\Socialnetwork\Helper\UserToGroup\RequestPopup::unsetHideRequestPopup([ 'groupId' => $groupId, 'userId' => $userId, ]); if ($groupFields["OPENED"] === "Y") { if ($autoSubscribe) { CSocNetLogEvents::AutoSubscribe($userId, SONET_ENTITY_GROUP, $groupId); } if (ModuleManager::isModuleInstalled('im')) { $chatNotificationResult = UserToGroup::addInfoToChat([ 'group_id' => $groupId, 'user_id' => $userId, 'action' => UserToGroup::CHAT_ACTION_IN, 'role' => $relationFields['ROLE'], ]); if (!$chatNotificationResult) { CSocNetUserToGroup::notifyImToModerators([ "TYPE" => "join", "RELATION_ID" => $ID, "USER_ID" => $userId, "GROUP_ID" => $groupId, "GROUP_NAME" => $groupFields["NAME"], ]); } } } elseif ( trim($requestConfirmUrl) !== '' && Loader::includeModule('im') ) { static $serverName; if (!$serverName) { $dbSite = CSite::GetByID(SITE_ID); $arSite = $dbSite->Fetch(); $serverName = htmlspecialcharsEx($arSite["SERVER_NAME"]); if ($serverName === '') { if (defined("SITE_SERVER_NAME") && SITE_SERVER_NAME !== '') { $serverName = SITE_SERVER_NAME; } else { $serverName = Option::get("main", "server_name"); } if ($serverName === '') { $serverName = $_SERVER["SERVER_NAME"]; } } $serverName = (CMain::IsHTTPS() ? "https" : "http")."://".$serverName; } // send sonet system messages to owner and (may be) moderators to accept or refuse request $FilterRole = ( $groupFields['INITIATE_PERMS'] === UserToGroupTable::ROLE_OWNER ? UserToGroupTable::ROLE_OWNER : UserToGroupTable::ROLE_MODERATOR ); $res = CSocNetUserToGroup::GetList( array("USER_ID" => "ASC"), array( "GROUP_ID" => $groupId, "<=ROLE" => $FilterRole, "USER_ACTIVE" => "Y" ), false, false, array("ID", "USER_ID", "USER_NAME", "USER_LAST_NAME", "USER_EMAIL") ); if ($res) { $groupSiteId = CSocNetGroup::GetDefaultSiteId($groupId, $groupFields["SITE_ID"] ?? false); $workgroupsPage = COption::GetOptionString("socialnetwork", "workgroups_page", "/workgroups/", SITE_ID); $groupUrlTemplate = Path::get('group_path_template'); $groupUrlTemplate = "#GROUPS_PATH#" . mb_substr($groupUrlTemplate, mb_strlen($workgroupsPage)); $groupUrl = str_replace(array("#group_id#", "#GROUP_ID#"), $groupId, $groupUrlTemplate); while ($recipientRelationFields = $res->fetch()) { $arTmp = CSocNetLogTools::ProcessPath( [ "GROUP_URL" => $groupUrl, ], $recipientRelationFields["USER_ID"], $groupSiteId ); $groupUrl = $arTmp["URLS"]["GROUP_URL"]; $domainName = ( mb_strpos($groupUrl, "http://") === 0 || mb_strpos($groupUrl, "https://") === 0 ? "" : ( isset($arTmp["DOMAIN"]) && !empty($arTmp["DOMAIN"]) ? "//".$arTmp["DOMAIN"] : "" ) ); $messageFields = array( "TO_USER_ID" => $recipientRelationFields["USER_ID"], "FROM_USER_ID" => $userId, "NOTIFY_TYPE" => IM_NOTIFY_CONFIRM, "NOTIFY_MODULE" => "socialnetwork", "NOTIFY_EVENT" => "invite_group_btn", "NOTIFY_TAG" => "SOCNET|REQUEST_GROUP|" . $userId . "|" . $groupId . "|" . $ID . "|" . $recipientRelationFields["USER_ID"], "NOTIFY_SUB_TAG" => "SOCNET|REQUEST_GROUP|" . $userId."|" . $groupId . "|" . $ID, "NOTIFY_TITLE" => str_replace( "#GROUP_NAME#", truncateText($groupFields["NAME"], 150), Loc::getMessage('SONET_UG_REQUEST_CONFIRM_TEXT_EMPTY') ), "NOTIFY_MESSAGE" => fn (?string $languageId = null) => str_replace( [ "#TEXT#", "#GROUP_NAME#", ], [ $message, "<a href=\"".$domainName.$groupUrl."\" class=\"bx-notifier-item-action\">".$groupFields["NAME"]."</a>" ], (empty($message) ? Loc::getMessage('SONET_UG_REQUEST_CONFIRM_TEXT_EMPTY', null, $languageId) : Loc::getMessage('SONET_UG_REQUEST_CONFIRM_TEXT', null, $languageId) ) ), "NOTIFY_BUTTONS" => [ [ "TITLE" => Loc::getMessage('SONET_UG_REQUEST_CONFIRM'), "VALUE" => "Y", "TYPE" => "accept", ], [ "TITLE" => Loc::getMessage('SONET_UG_REQUEST_REJECT'), "VALUE" => "N", "TYPE" => "cancel", ], ], ); $groupUrl = $serverName.str_replace("#group_id#", $groupId, Path::get('group_path_template')); $messageFields["NOTIFY_MESSAGE_OUT"] = fn (?string $languageId = null) => str_replace( [ "#TEXT#", "#GROUP_NAME#", ], [ $message, "<a href=\"".$domainName.$groupUrl."\" class=\"bx-notifier-item-action\">".$groupFields["NAME"]."</a>" ], (empty($message) ? Loc::getMessage('SONET_UG_REQUEST_CONFIRM_TEXT_EMPTY', null, $languageId) : Loc::getMessage('SONET_UG_REQUEST_CONFIRM_TEXT', null, $languageId) ) ) . "\n\n".Loc::getMessage("SONET_UG_GROUP_LINK", null, $languageId).$groupUrl . "\n\n".Loc::getMessage("SONET_UG_REQUEST_CONFIRM_REJECT", null, $languageId).": ".$requestConfirmUrl ; CIMNotify::Add($messageFields); } } } return true; } public static function SendRequestToJoinGroup($senderUserId, $userId, $groupId, $message, $sendMail = true): bool { global $APPLICATION, $USER; $senderUserId = (int)$senderUserId; if ($senderUserId <= 0) { $APPLICATION->ThrowException(Loc::getMessage('SONET_UR_EMPTY_USERID'), "ERROR_SENDERID"); return false; } $userId = (int)$userId; if ($userId <= 0) { $APPLICATION->ThrowException(Loc::getMessage("SONET_UR_EMPTY_USERID"), "ERROR_USERID"); return false; } $groupId = (int)$groupId; if ($groupId <= 0) { $APPLICATION->ThrowException(Loc::getMessage("SONET_UR_EMPTY_GROUPID"), "ERROR_GROUPID"); return false; } $groupFields = WorkgroupTable::getList([ 'select' => [ 'NAME', 'INITIATE_PERMS', 'OWNER_ID', ], 'filter' => ['ID' => $groupId], ])->fetch(); if (!$groupFields || !is_array($groupFields)) { $APPLICATION->ThrowException(Loc::getMessage("SONET_UG_ERROR_NO_GROUP_ID"), "ERROR_NO_GROUP"); return false; } $arGroupSites = array(); $rsGroupSite = CSocNetGroup::GetSite($groupId); while ($arGroupSite = $rsGroupSite->Fetch()) { $arGroupSites[] = $arGroupSite["LID"]; } $userRole = CSocNetUserToGroup::GetUserRole($senderUserId, $groupId); $userIsMember = ($userRole && in_array($userRole, UserToGroupTable::getRolesMember(), true)); $canInitiate = ( $USER->IsAdmin() || CSocNetUser::IsCurrentUserModuleAdmin($arGroupSites) || ( $userRole && ( ( $groupFields["INITIATE_PERMS"] === UserToGroupTable::ROLE_OWNER && $senderUserId === (int)$groupFields["OWNER_ID"] ) || ( $groupFields["INITIATE_PERMS"] === UserToGroupTable::ROLE_MODERATOR && in_array($userRole, [ UserToGroupTable::ROLE_OWNER, UserToGroupTable::ROLE_MODERATOR ], true) ) || ( $groupFields["INITIATE_PERMS"] === UserToGroupTable::ROLE_USER && $userIsMember ) ) ) ); if (!$canInitiate) { $APPLICATION->ThrowException(Loc::getMessage("SONET_UG_ERROR_NO_PERMS"), "ERROR_NO_PERMS"); return false; } $relationFields = array( "USER_ID" => $userId, "GROUP_ID" => $groupId, "ROLE" => UserToGroupTable::ROLE_REQUEST, "=DATE_CREATE" => CDatabase::CurrentTimeFunction(), "=DATE_UPDATE" => CDatabase::CurrentTimeFunction(), "MESSAGE" => str_replace( [ "#TEXT#", "#GROUP_NAME#" ], [ $message, $groupFields["NAME"] ], ( empty($message) ? Loc::getMessage("SONET_UG_INVITE_CONFIRM_TEXT_EMPTY") : Loc::getMessage("SONET_UG_INVITE_CONFIRM_TEXT") ) ), "INITIATED_BY_TYPE" => SONET_INITIATED_BY_GROUP, "INITIATED_BY_USER_ID" => $senderUserId, "SEND_MAIL" => ($sendMail ? "Y" : "N") ); $relationId = CSocNetUserToGroup::Add($relationFields); if (!$relationId) { $errorMessage = ""; if ($e = $APPLICATION->GetException()) { $errorMessage = $e->GetString(); } if ($errorMessage === '') { $errorMessage = Loc::getMessage('SONET_UR_ERROR_CREATE_USER2GROUP'); } $APPLICATION->ThrowException($errorMessage, "ERROR_CREATE_USER2GROUP"); return false; } $userIsConfirmed = true; $rsInvitedUser = CUser::getList( 'ID', 'ASC', ['ID' => $userId], [ 'FIELDS' => [ 'ID', 'LAST_LOGIN', 'LAST_ACTIVITY_DATE', 'UF_DEPARTMENT', ], 'SELECT' => ['UF_DEPARTMENT'], ] ); $arInvitedUser = $rsInvitedUser->Fetch(); if ( ( !is_array($arInvitedUser["UF_DEPARTMENT"]) || (int) ($arInvitedUser["UF_DEPARTMENT"][0] ?? null) <= 0 ) // extranet && ($arInvitedUser["LAST_LOGIN"] <= 0) && $arInvitedUser["LAST_ACTIVITY_DATE"] == '' ) { $userIsConfirmed = false; } if ( $userIsConfirmed && Loader::includeModule('im') ) { $messageFields = [ "MESSAGE_TYPE" => IM_MESSAGE_SYSTEM, "TO_USER_ID" => (int)$relationFields['USER_ID'], "FROM_USER_ID" => (int)$relationFields['INITIATED_BY_USER_ID'], "NOTIFY_TYPE" => IM_NOTIFY_CONFIRM, "NOTIFY_MODULE" => "socialnetwork", "NOTIFY_EVENT" => "invite_group_btn", "NOTIFY_TAG" => "SOCNET|INVITE_GROUP|" . $userId . "|" . $relationId, "NOTIFY_TITLE" => fn (?string $languageId = null) => str_replace( "#GROUP_NAME#", truncateText($groupFields["NAME"], 150), Loc::getMessage("SONET_UG_INVITE_CONFIRM_TEXT_EMPTY", null, $languageId) ), "NOTIFY_MESSAGE" => fn (?string $languageId = null) => str_replace( [ "#TEXT#", "#GROUP_NAME#" ], [ $message, $groupFields["NAME"] ], ( empty($message) ? Loc::getMessage("SONET_UG_INVITE_CONFIRM_TEXT_EMPTY", null, $languageId) : Loc::getMessage("SONET_UG_INVITE_CONFIRM_TEXT", null, $languageId) ) ), "NOTIFY_BUTTONS" => [ [ 'TITLE' => Loc::getMessage('SONET_UG_INVITE_CONFIRM'), 'VALUE' => 'Y', 'TYPE' => 'accept', ], [ 'TITLE' => Loc::getMessage('SONET_UG_INVITE_REJECT'), 'VALUE' => 'N', 'TYPE' => 'cancel', ], ], ]; $siteId = ( ( !is_array($arInvitedUser["UF_DEPARTMENT"]) || (int)$arInvitedUser["UF_DEPARTMENT"][0] <= 0 ) && Loader::includeModule('extranet') ? CExtranet::GetExtranetSiteID() : SITE_ID ); $dbSite = CSite::GetByID($siteId); $arSite = $dbSite->Fetch(); $serverName = htmlspecialcharsEx($arSite["SERVER_NAME"]); if (!$serverName) { $serverName = ( defined("SITE_SERVER_NAME") && SITE_SERVER_NAME !== '' ? SITE_SERVER_NAME : Option::get('main', 'server_name') ); } if (!$serverName) { $serverName = $_SERVER["SERVER_NAME"]; } $serverName = (CMain::IsHTTPS() ? "https" : "http")."://".$serverName; $requestUrl = Option::get( "socialnetwork", "user_request_page", ( ModuleManager::isModuleInstalled('intranet') ? "/company/personal/user/#USER_ID#/requests/" : "/club/user/#USER_ID#/requests/" ), $siteId ); $requestUrl = $serverName.str_replace(array("#USER_ID#", "#user_id#"), $userId, $requestUrl); $groupUrl = $serverName.str_replace("#group_id#", $groupId, Path::get('group_path_template', $siteId)); $messageFields['NOTIFY_MESSAGE_OUT'] = fn (?string $languageId = null) => str_replace( [ "#TEXT#", "#GROUP_NAME#" ], [ $message, $groupFields["NAME"] ], ( empty($message) ? Loc::getMessage("SONET_UG_INVITE_CONFIRM_TEXT_EMPTY", null, $languageId) : Loc::getMessage("SONET_UG_INVITE_CONFIRM_TEXT", null, $languageId) ) ) . "\n\n" . Loc::getMessage('SONET_UG_GROUP_LINK', null, $languageId) . $groupUrl . "\n\n" . Loc::getMessage('SONET_UG_INVITE_CONFIRM', null, $languageId) . ": " . $requestUrl . '?INVITE_GROUP=' . $relationId . '&CONFIRM=Y' . "\n\n" . Loc::getMessage('SONET_UG_INVITE_REJECT', null, $languageId) . ": " . $requestUrl . '?INVITE_GROUP=' . $relationId . '&CONFIRM=N' ; CIMNotify::Add($messageFields); } $events = GetModuleEvents("socialnetwork", "OnSocNetSendRequestToJoinGroup"); while ($arEvent = $events->Fetch()) { ExecuteModuleEventEx($arEvent, [ $relationId, $relationFields ]); } CSocNetUserToGroup::__SpeedFileCreate($userId); return true; } public static function ConfirmRequestToBeMember($userId, $groupId, $relationIdList, $autoSubscribe = true): bool // request from a user confirmed by a moderator { global $APPLICATION, $USER; $userId = (int)$userId; if ($userId <= 0) { $APPLICATION->ThrowException(Loc::getMessage("SONET_UR_EMPTY_USERID"), "ERROR_USERID"); return false; } $groupId = (int)$groupId; if ($groupId <= 0) { $APPLICATION->ThrowException(Loc::getMessage("SONET_UR_EMPTY_GROUPID"), "ERROR_GROUPID"); return false; } if (!is_array($relationIdList)) { return true; } $arGroup = CSocNetGroup::getById($groupId); if (!$arGroup || !is_array($arGroup)) { $APPLICATION->ThrowException(Loc::getMessage("SONET_UG_ERROR_NO_GROUP_ID"), "ERROR_NO_GROUP"); return false; } $groupSiteIdList = array(); $res = CSocNetGroup::GetSite($groupId); while ($groupSiteFields = $res->fetch()) { $groupSiteIdList[] = $groupSiteFields["LID"]; } $userRole = CSocNetUserToGroup::GetUserRole($userId, $groupId); $userIsMember = ( $userRole && in_array($userRole, UserToGroupTable::getRolesMember(), true) ); $canInitiate = ( $USER->IsAdmin() || CSocNetUser::IsCurrentUserModuleAdmin($groupSiteIdList) || ( $userRole && ( ( $arGroup["INITIATE_PERMS"] === UserToGroupTable::ROLE_OWNER && $userId === (int)$arGroup["OWNER_ID"] ) || ( $arGroup["INITIATE_PERMS"] === UserToGroupTable::ROLE_MODERATOR && in_array($userRole, [ UserToGroupTable::ROLE_OWNER, UserToGroupTable::ROLE_MODERATOR ], true) ) || ( $arGroup["INITIATE_PERMS"] === UserToGroupTable::ROLE_USER && $userIsMember ) ) ) ); if (!$canInitiate) { $APPLICATION->ThrowException(Loc::getMessage("SONET_UG_ERROR_NO_PERMS"), "ERROR_NO_PERMS"); return false; } $bSuccess = true; $arSuccessRelations = array(); $chatNotificationResult = false; foreach ($relationIdList as $relationId) { $relationId = (int)$relationId; if ($relationId <= 0) { continue; } $relationFields = CSocNetUserToGroup::GetByID($relationId); if (!$relationFields) { continue; } if ( (int)$relationFields["GROUP_ID"] !== $groupId || $relationFields["INITIATED_BY_TYPE"] !== SONET_INITIATED_BY_USER || $relationFields["ROLE"] !== UserToGroupTable::ROLE_REQUEST ) { continue; } $arFields = array( "ROLE" => UserToGroupTable::ROLE_USER, "=DATE_UPDATE" => CDatabase::CurrentTimeFunction(), ); if (CSocNetUserToGroup::Update($relationFields["ID"], $arFields)) { $arSuccessRelations[] = $relationFields; if ($autoSubscribe) { CSocNetLogEvents::AutoSubscribe($relationFields["USER_ID"], SONET_ENTITY_GROUP, $groupId); } $chatNotificationResult = UserToGroup::addInfoToChat([ 'group_id' => $groupId, 'user_id' => $relationFields["USER_ID"], 'action' => UserToGroup::CHAT_ACTION_IN, 'role' => $arFields['ROLE'], ]); if ( !$chatNotificationResult && Loader::includeModule('im') ) { $groupSiteId = CSocNetGroup::GetDefaultSiteId($groupId, $arGroup["SITE_ID"]); $workgroupsPage = COption::GetOptionString("socialnetwork", "workgroups_page", "/workgroups/", SITE_ID); $groupUrlTemplate = Path::get('group_path_template'); $groupUrlTemplate = "#GROUPS_PATH#".mb_substr($groupUrlTemplate, mb_strlen($workgroupsPage)); $arTmp = CSocNetLogTools::ProcessPath( array( "GROUP_URL" => str_replace(array("#group_id#", "#GROUP_ID#"), $groupId, $groupUrlTemplate) ), $relationFields["USER_ID"], $groupSiteId ); $groupUrl = $arTmp["URLS"]["GROUP_URL"]; $serverName = ( mb_strpos($groupUrl, "http://") === 0 || mb_strpos($groupUrl, "https://") === 0 ? "" : $arTmp["SERVER_NAME"] ); $domainName = ( mb_strpos($groupUrl, "http://") === 0 || mb_strpos($groupUrl, "https://") === 0 ? "" : ( isset($arTmp["DOMAIN"]) && !empty($arTmp["DOMAIN"]) ? "//".$arTmp["DOMAIN"] : "" ) ); $arMessageFields = array( "MESSAGE_TYPE" => IM_MESSAGE_SYSTEM, "TO_USER_ID" => $relationFields["USER_ID"], "FROM_USER_ID" => $userId, "NOTIFY_TYPE" => IM_NOTIFY_FROM, "NOTIFY_MODULE" => "socialnetwork", "NOTIFY_EVENT" => "invite_group", "NOTIFY_TAG" => "SOCNET|INVITE_GROUP|" . (int)$relationFields["USER_ID"] . "|" . (int)$relationFields["ID"], "NOTIFY_MESSAGE" => fn (?string $languageId = null) => Loc::getMessage( "SONET_UG_CONFIRM_MEMBER_MESSAGE_G", ['#NAME#' => "<a href=\"".$domainName.$groupUrl."\" class=\"bx-notifier-item-action\">".$arGroup["NAME"]."</a>"], $languageId ) , "NOTIFY_MESSAGE_OUT" => fn (?string $languageId = null) => Loc::getMessage( "SONET_UG_CONFIRM_MEMBER_MESSAGE_G", ['#NAME#' => $arGroup['NAME']], $languageId ) . " (".$serverName.$groupUrl.")" ); CIMNotify::DeleteBySubTag("SOCNET|REQUEST_GROUP|".$relationFields["USER_ID"]."|".$relationFields["GROUP_ID"]."|".$relationFields["ID"]); CIMNotify::Add($arMessageFields); } if (Loader::includeModule('pull')) { \Bitrix\Pull\Event::add((int)$relationFields['USER_ID'], [ 'module_id' => 'socialnetwork', 'command' => 'workgroup_request_accepted', 'params' => [ 'initiatedByType' => $relationFields['INITIATED_BY_TYPE'], ], ]); } \Bitrix\Socialnetwork\Helper\UserToGroup\RequestPopup::unsetHideRequestPopup([ 'groupId' => (int)$relationFields['GROUP_ID'], 'userId' => (int)$relationFields['USER_ID'], ]); } else { $errorMessage = ""; if ($e = $APPLICATION->GetException()) { $errorMessage = $e->GetString(); } if ($errorMessage === '') { $errorMessage = Loc::getMessage('SONET_UR_ERROR_CREATE_USER2GROUP'); } $APPLICATION->ThrowException($errorMessage, "ERROR_CONFIRM_MEMBER"); $bSuccess = false; } } if ( !empty($arSuccessRelations) && !$chatNotificationResult ) { foreach ($arSuccessRelations as $arRel) { CSocNetUserToGroup::notifyImToModerators(array( "TYPE" => "join", "RELATION_ID" => $arRel["ID"], "USER_ID" => $arRel["USER_ID"], "GROUP_ID" => $arRel["GROUP_ID"], "GROUP_NAME" => $arRel["GROUP_NAME"], "EXCLUDE_USERS" => array($USER->GetID()) )); } } return $bSuccess; } public static function RejectRequestToBeMember($userId, $groupId, $relationIdList): bool { global $APPLICATION, $USER; $userId = (int)$userId; if ($userId <= 0) { $APPLICATION->ThrowException(Loc::getMessage('SONET_UR_EMPTY_USERID'), "ERROR_USERID"); return false; } $groupId = (int)$groupId; if ($groupId <= 0) { $APPLICATION->ThrowException(Loc::getMessage('SONET_UR_EMPTY_GROUPID'), "ERROR_GROUPID"); return false; } if (!is_array($relationIdList)) { return true; } $groupFields = WorkgroupTable::getList([ 'select' => [ 'NAME', 'INITIATE_PERMS', 'OWNER_ID', ], 'filter' => ['ID' => $groupId], ])->fetch(); if (!$groupFields || !is_array($groupFields)) { $APPLICATION->ThrowException(Loc::getMessage("SONET_UG_ERROR_NO_GROUP_ID"), "ERROR_NO_GROUP"); return false; } $groupSiteIdList = []; $rsGroupSite = CSocNetGroup::GetSite($groupId); while ($groupSiteFields = $rsGroupSite->fetch()) { $groupSiteIdList[] = $groupSiteFields["LID"]; } $userRole = CSocNetUserToGroup::GetUserRole($userId, $groupId); $userIsMember = ($userRole && in_array($userRole, UserToGroupTable::getRolesMember(), true)); $bCanInitiate = ( $USER->IsAdmin() || CSocNetUser::IsCurrentUserModuleAdmin($groupSiteIdList) || ( $userRole && ( ( $groupFields["INITIATE_PERMS"] === UserToGroupTable::ROLE_OWNER && $userId === (int)$groupFields["OWNER_ID"] ) || ( $groupFields["INITIATE_PERMS"] === UserToGroupTable::ROLE_MODERATOR && in_array($userRole, [ UserToGroupTable::ROLE_OWNER, UserToGroupTable::ROLE_MODERATOR ], true) ) || ( $groupFields["INITIATE_PERMS"] === UserToGroupTable::ROLE_USER && $userIsMember ) ) ) ); if (!$bCanInitiate) { $APPLICATION->ThrowException(GetMessage("SONET_UG_ERROR_NO_PERMS"), "ERROR_NO_PERMS"); return false; } $bSuccess = true; foreach ($relationIdList as $relationId) { $relationId = (int)$relationId; if ($relationId <= 0) { continue; } $arRelation = CSocNetUserToGroup::GetByID($relationId); if (!$arRelation) { continue; } if ( (int)$arRelation["GROUP_ID"] !== $groupId || $arRelation["INITIATED_BY_TYPE"] !== SONET_INITIATED_BY_USER || $arRelation["ROLE"] !== UserToGroupTable::ROLE_REQUEST ) { continue; } if (CSocNetUserToGroup::Delete($arRelation["ID"])) { $arMessageFields = array( "FROM_USER_ID" => $userId, "TO_USER_ID" => $arRelation["USER_ID"], "MESSAGE" => fn (?string $languageId = null) => Loc::getMessage( 'SONET_UG_REJECT_MEMBER_MESSAGE_G', [ '#NAME#' => $groupFields['NAME'] ], $languageId ) , "=DATE_CREATE" => CDatabase::CurrentTimeFunction(), "MESSAGE_TYPE" => SONET_MESSAGE_SYSTEM ); CSocNetMessages::Add($arMessageFields); \Bitrix\Socialnetwork\Helper\UserToGroup\RequestPopup::unsetHideRequestPopup([ 'groupId' => (int)$groupId, 'userId' => (int)$arRelation['USER_ID'], ]); } else { $errorMessage = ""; if ($e = $APPLICATION->GetException()) { $errorMessage = $e->GetString(); } if ($errorMessage === '') { $errorMessage = Loc::getMessage("SONET_UR_ERROR_CREATE_USER2GROUP"); } $APPLICATION->ThrowException($errorMessage, "ERROR_CONFIRM_MEMBER"); $bSuccess = false; } } return $bSuccess; } public static function UserConfirmRequestToBeMember($targetUserID, $relationID, $bAutoSubscribe = true): bool // request from group confirmed by a user { global $APPLICATION; $targetUserID = (int)$targetUserID; if ($targetUserID <= 0) { $APPLICATION->ThrowException(GetMessage("SONET_UR_EMPTY_USERID"), "ERROR_SENDER_USER_ID"); return false; } $relationID = (int)$relationID; if ($relationID <= 0) { $APPLICATION->ThrowException(GetMessage("SONET_UR_EMPTY_RELATIONID"), "ERROR_RELATION_ID"); return false; } $dbResult = CSocNetUserToGroup::GetList( array(), array( "ID" => $relationID, "USER_ID" => $targetUserID, "ROLE" => UserToGroupTable::ROLE_REQUEST, "INITIATED_BY_TYPE" => SONET_INITIATED_BY_GROUP ), false, false, array("ID", "USER_ID", "INITIATED_BY_USER_ID", "GROUP_ID", "GROUP_VISIBLE", "GROUP_SITE_ID", "GROUP_NAME") ); if ($arResult = $dbResult->Fetch()) { if (!empty($arResult['GROUP_NAME'])) { $arResult['GROUP_NAME'] = Emoji::decode($arResult['GROUP_NAME']); } $arFields = array( "ROLE" => UserToGroupTable::ROLE_USER, "=DATE_UPDATE" => CDatabase::CurrentTimeFunction(), ); if (CSocNetUserToGroup::Update($arResult["ID"], $arFields)) { $events = GetModuleEvents("socialnetwork", "OnSocNetUserConfirmRequestToBeMember"); while ($arEvent = $events->Fetch()) { ExecuteModuleEventEx($arEvent, array($arResult["ID"], $arResult)); } $moderators = UserToGroupTable::getGroupModerators((int)$arResult['GROUP_ID']); EventService\Service::addEvent( EventService\EventDictionary::EVENT_WORKGROUP_MEMBER_REQUEST_CONFIRM, [ 'GROUP_ID' => (int)$arResult['GROUP_ID'], 'RECEPIENTS' => array_map(function ($row) { return $row['USER_ID']; }, $moderators), ] ); if ($bAutoSubscribe) { CSocNetLogEvents::AutoSubscribe($targetUserID, SONET_ENTITY_GROUP, $arResult["GROUP_ID"]); } if (Loader::includeModule('im')) { $groupSiteId = CSocNetGroup::GetDefaultSiteId($arResult["GROUP_ID"], $arResult["GROUP_SITE_ID"]); CIMNotify::DeleteByTag("SOCNET|INVITE_GROUP|" . (int)$targetUserID . "|" . (int)$relationID); $workgroupsPage = COption::GetOptionString("socialnetwork", "workgroups_page", "/workgroups/", $groupSiteId); $groupUrlTemplate = Path::get('group_path_template', $groupSiteId); $groupUrlTemplate = "#GROUPS_PATH#".mb_substr($groupUrlTemplate, mb_strlen($workgroupsPage)); $groupUrl = str_replace(array("#group_id#", "#GROUP_ID#"), $arResult["GROUP_ID"], $groupUrlTemplate); $arTmp = CSocNetLogTools::ProcessPath( array( "GROUP_URL" => $groupUrl ), $arResult["INITIATED_BY_USER_ID"], $groupSiteId ); $url = $arTmp["URLS"]["GROUP_URL"]; $serverName = ( mb_strpos($url, "http://") === 0 || mb_strpos($url, "https://") === 0 ? "" : $arTmp["SERVER_NAME"] ); $domainName = ( mb_strpos($url, "http://") === 0 || mb_strpos($url, "https://") === 0 ? "" : ( isset($arTmp["DOMAIN"]) && !empty($arTmp["DOMAIN"]) ? "//".$arTmp["DOMAIN"] : "" ) ); $arMessageFields = array( "MESSAGE_TYPE" => IM_MESSAGE_SYSTEM, "TO_USER_ID" => $arResult['USER_ID'], "NOTIFY_TYPE" => IM_NOTIFY_SYSTEM, "NOTIFY_MODULE" => "socialnetwork", "NOTIFY_EVENT" => "invite_group", "NOTIFY_TAG" => "SOCNET|INVITE_GROUP|" . (int)$arResult['USER_ID'] . "|". $relationID, "NOTIFY_MESSAGE" => fn (?string $languageId = null) => Loc::getMessage( "SONET_UG_CONFIRM_MEMBER_MESSAGE_G", ['#NAME#' => "<a href=\"".$domainName.$url."\" class=\"bx-notifier-item-action\">".$arResult["GROUP_NAME"]."</a>"], $languageId ) , "NOTIFY_MESSAGE_OUT" => fn (?string $languageId = null) => Loc::getMessage( "SONET_UG_CONFIRM_MEMBER_MESSAGE_G", ['#NAME#' => $arResult['GROUP_NAME']], $languageId ) . " (".$serverName.$url.")" , ); CIMNotify::Add($arMessageFields); $collab = CollabRegistry::getInstance()->get($arResult["GROUP_ID"]); if ($collab !== null) { $senderId = (int)$arResult["USER_ID"]; $chatNotificationResult = ActionMessageFactory::getInstance() ->getActionMessage(ActionType::AcceptUser, $collab->getId(), $senderId) ->send(); } else { $chatNotificationResult = UserToGroup::addInfoToChat([ 'group_id' => $arResult["GROUP_ID"], 'user_id' => $arResult["USER_ID"], 'action' => UserToGroup::CHAT_ACTION_IN, 'role' => $arFields['ROLE'], ]); } if (!$chatNotificationResult) { $arMessageFields = array( "MESSAGE_TYPE" => IM_MESSAGE_SYSTEM, "TO_USER_ID" => $arResult["INITIATED_BY_USER_ID"], "FROM_USER_ID" => $arResult['USER_ID'], "NOTIFY_TYPE" => IM_NOTIFY_FROM, "NOTIFY_MODULE" => "socialnetwork", "NOTIFY_EVENT" => "invite_group", "NOTIFY_TAG" => "SOCNET|INVITE_GROUP_SUCCESS|" . (int)$arResult["GROUP_ID"], "NOTIFY_MESSAGE" => fn (?string $languageId = null) => Loc::getMessage( "SONET_UG_CONFIRM_MEMBER_MESSAGE_MSGVER_1", ["#NAME#" => "<a href=\"".$domainName.$url."\" class=\"bx-notifier-item-action\">".$arResult["GROUP_NAME"]."</a>"], $languageId ) , "NOTIFY_MESSAGE_OUT" => fn (?string $languageId = null) => Loc::getMessage( "SONET_UG_CONFIRM_MEMBER_MESSAGE_MSGVER_1", ['#NAME#' => $arResult['GROUP_NAME'], $languageId] ) ." (".$serverName . $url.")", ); CIMNotify::Add($arMessageFields); CSocNetUserToGroup::NotifyImToModerators(array( "TYPE" => "join", "RELATION_ID" => $arResult["ID"], "USER_ID" => $arResult["USER_ID"], "GROUP_ID" => $arResult["GROUP_ID"], "GROUP_NAME" => htmlspecialcharsbx($arResult["GROUP_NAME"]), "EXCLUDE_USERS" => array($arResult["INITIATED_BY_USER_ID"]) )); } } } else { $errorMessage = ""; if ($e = $APPLICATION->GetException()) { $errorMessage = $e->GetString(); } if ($errorMessage === '') { $errorMessage = Loc::getMessage('SONET_UR_ERROR_CREATE_USER2GROUP'); } $APPLICATION->ThrowException($errorMessage, "ERROR_CREATE_RELATION"); return false; } } else { $APPLICATION->ThrowException(GetMessage("SONET_NO_USER2GROUP"), "ERROR_NO_GROUP_REQUEST"); return false; } CSocNetUserToGroup::__SpeedFileCheckMessages($targetUserID); return true; } public static function UserRejectRequestToBeMember($targetUserID, $relationID): bool { global $APPLICATION; $targetUserID = (int)$targetUserID; if ($targetUserID <= 0) { $APPLICATION->ThrowException(GetMessage("SONET_UR_EMPTY_USERID"), "ERROR_SENDER_USER_ID"); return false; } $relationID = (int)$relationID; if ($relationID <= 0) { $APPLICATION->ThrowException(GetMessage("SONET_UR_EMPTY_RELATIONID"), "ERROR_RELATION_ID"); return false; } $dbResult = CSocNetUserToGroup::GetList( array(), array( "ID" => $relationID, "USER_ID" => $targetUserID, "ROLE" => UserToGroupTable::ROLE_REQUEST, "INITIATED_BY_TYPE" => SONET_INITIATED_BY_GROUP ), false, false, array("ID", "USER_ID", "GROUP_ID", "GROUP_SITE_ID", "INITIATED_BY_USER_ID", "GROUP_NAME") ); if ($arResult = $dbResult->Fetch()) { if (!empty($arResult['GROUP_NAME'])) { $arResult['GROUP_NAME'] = Emoji::decode($arResult['GROUP_NAME']); } if (CSocNetUserToGroup::Delete($arResult["ID"])) { $events = GetModuleEvents("socialnetwork", "OnSocNetUserRejectRequestToBeMember"); while ($arEvent = $events->Fetch()) { ExecuteModuleEventEx($arEvent, array($arResult["ID"], $arResult)); } if (Loader::includeModule('im')) { $groupSiteId = CSocNetGroup::GetDefaultSiteId($arResult["GROUP_ID"], $arResult["GROUP_SITE_ID"]); $groupUrl = str_replace( [ "#group_id#", "#GROUP_ID#" ], $arResult["GROUP_ID"], Path::get('group_path_template', $groupSiteId) ); $arTmp = CSocNetLogTools::ProcessPath( array( "GROUP_URL" => $groupUrl ), $arResult["INITIATED_BY_USER_ID"], $groupSiteId ); $url = $arTmp["URLS"]["GROUP_URL"]; $serverName = ( mb_strpos($url, "http://") === 0 || mb_strpos($url, "https://") === 0 ? "" : $arTmp["SERVER_NAME"] ); $domainName = ( mb_strpos($url, "http://") === 0 || mb_strpos($url, "https://") === 0 ? "" : ( isset($arTmp["DOMAIN"]) && !empty($arTmp["DOMAIN"]) ? "//".$arTmp["DOMAIN"] : "" ) ); $arMessageFields = array( "MESSAGE_TYPE" => IM_MESSAGE_SYSTEM, "TO_USER_ID" => $arResult["INITIATED_BY_USER_ID"], "FROM_USER_ID" => $arResult['USER_ID'], "NOTIFY_TYPE" => IM_NOTIFY_FROM, "NOTIFY_MODULE" => "socialnetwork", "NOTIFY_EVENT" => "invite_group", "NOTIFY_TAG" => "SOCNET|INVITE_GROUP_REJECT|" . (int)$arResult["GROUP_ID"], "NOTIFY_MESSAGE" => fn (?string $languageId = null) => Loc::getMessage( "SONET_UG_REJECT_MEMBER_MESSAGE_MSGVER_1", ["#NAME#" => "<a href=\"".$domainName.$url."\" class=\"bx-notifier-item-action\">".$arResult["GROUP_NAME"]."</a>"], $languageId ) , "NOTIFY_MESSAGE_OUT" => fn (?string $languageId = null) => Loc::getMessage( "SONET_UG_REJECT_MEMBER_MESSAGE_MSGVER_1", ['#NAME#' => $arResult['GROUP_NAME']], $languageId ) . " (".$serverName.$url.")" , ); CIMNotify::Add($arMessageFields); } } else { $errorMessage = ""; if ($e = $APPLICATION->GetException()) { $errorMessage = $e->GetString(); } if ($errorMessage === '') { $errorMessage = Loc::getMessage('SONET_UR_ERROR_CREATE_USER2GROUP'); } $APPLICATION->ThrowException($errorMessage, "ERROR_DELETE_RELATION"); return false; } } else { $APPLICATION->ThrowException(GetMessage("SONET_NO_USER2GROUP"), "ERROR_NO_MEMBER_REQUEST"); return false; } CSocNetUserToGroup::__SpeedFileCheckMessages($targetUserID); return true; } public static function TransferModerator2Member($userID, $groupId, $relationIdList): bool { global $APPLICATION, $USER; $userID = (int)$userID; if ($userID <= 0) { $APPLICATION->ThrowException(GetMessage("SONET_UR_EMPTY_USERID"), "ERROR_USERID"); return false; } $groupId = (int)$groupId; if ($groupId <= 0) { $APPLICATION->ThrowException(GetMessage("SONET_UR_EMPTY_GROUPID"), "ERROR_GROUPID"); return false; } if (!is_array($relationIdList)) { return true; } $arGroup = WorkgroupTable::getList([ 'select' => [ 'SITE_ID', 'NAME', ], 'filter' => ['ID' => $groupId], ])->fetch(); if (!$arGroup || !is_array($arGroup)) { $APPLICATION->ThrowException(GetMessage("SONET_UG_ERROR_NO_GROUP_ID"), "ERROR_NO_GROUP"); return false; } $bSuccess = true; $arSuccessRelations = array(); $bIMIncluded = false; $groupSiteId = SITE_ID; if (Loader::includeModule('im')) { $bIMIncluded = true; $groupSiteId = CSocNetGroup::GetDefaultSiteId($groupId, $arGroup["SITE_ID"]); } $workgroupsPage = COption::GetOptionString("socialnetwork", "workgroups_page", "/workgroups/", $groupSiteId); $groupUrlTemplate = Path::get('group_path_template', $groupSiteId); $groupUrlTemplate = "#GROUPS_PATH#".mb_substr($groupUrlTemplate, mb_strlen($workgroupsPage)); $groupUrl = str_replace(array("#group_id#", "#GROUP_ID#"), $groupId, $groupUrlTemplate); $relationsToUpdateCount = 0; foreach ($relationIdList as $relationId) { $relationId = (int)$relationId; if ($relationId <= 0) { continue; } $arRelation = CSocNetUserToGroup::GetByID($relationId); if ( !$arRelation || (int)$arRelation["GROUP_ID"] !== $groupId || $arRelation["ROLE"] !== UserToGroupTable::ROLE_MODERATOR ) { continue; } $relationsToUpdateCount++; $arFields = array( "ROLE" => UserToGroupTable::ROLE_USER, "=DATE_UPDATE" => CDatabase::CurrentTimeFunction(), ); if (CSocNetUserToGroup::Update($arRelation["ID"], $arFields)) { $arSuccessRelations[] = $arRelation; if ($bIMIncluded) { $arTmp = CSocNetLogTools::ProcessPath( array( "GROUP_URL" => $groupUrl ), $arRelation["USER_ID"], $groupSiteId ); $groupUrl = $arTmp["URLS"]["GROUP_URL"]; $serverName = ( mb_strpos($groupUrl, "http://") === 0 || mb_strpos($groupUrl, "https://") === 0 ? "" : $arTmp["SERVER_NAME"] ); $domainName = ( mb_strpos($groupUrl, "http://") === 0 || mb_strpos($groupUrl, "https://") === 0 ? "" : ( isset($arTmp["DOMAIN"]) && !empty($arTmp["DOMAIN"]) ? "//".$arTmp["DOMAIN"] : "" ) ); $arMessageFields = array( "TO_USER_ID" => $arRelation["USER_ID"], "FROM_USER_ID" => $userID, "NOTIFY_TYPE" => IM_NOTIFY_FROM, "NOTIFY_MODULE" => "socialnetwork", "NOTIFY_EVENT" => "moderators_group", "NOTIFY_TAG" => "SOCNET|MOD_GROUP|" . (int)$userID . "|" . $groupId . "|" . $arRelation["ID"] . "|" . $arRelation["USER_ID"], "NOTIFY_MESSAGE" => fn (?string $languageId = null) => Loc::getMessage( "SONET_UG_MOD2MEMBER_MESSAGE", ['#NAME#' => "<a href=\"".$domainName.$groupUrl."\" class=\"bx-notifier-item-action\">".$arGroup["NAME"]."</a>"], $languageId ) , "NOTIFY_MESSAGE_OUT" => fn (?string $languageId = null) => Loc::getMessage( "SONET_UG_MOD2MEMBER_MESSAGE", ['#NAME#' => $arGroup["NAME"]], $languageId ) . " (".$serverName.$groupUrl.")" , ); CIMNotify::Add($arMessageFields); } } else { $errorMessage = ""; if ($e = $APPLICATION->GetException()) { $errorMessage = $e->GetString(); } if ($errorMessage === '') { $errorMessage = Loc::getMessage("SONET_UR_ERROR_CREATE_USER2GROUP"); } $APPLICATION->ThrowException($errorMessage, "ERROR_MOD2MEMBER"); $bSuccess = false; } } if ($relationsToUpdateCount <= 0) { $APPLICATION->ThrowException(GetMessage("SONET_UR_ERROR_MEM2MOD_EMPTY_CORRECT_LIST"), "MOD2MEM_EMPTY_CORRECT_LIST"); return false; } $successfulUserIdList = array(); foreach ($arSuccessRelations as $arRel) { $arNotifyParams = array( "TYPE" => "unmoderate", "RELATION_ID" => $arRel["ID"], "USER_ID" => $arRel["USER_ID"], "GROUP_ID" => $arRel["GROUP_ID"], "GROUP_NAME" => $arRel["GROUP_NAME"], "EXCLUDE_USERS" => array($USER->GetID()) ); CSocNetUserToGroup::NotifyImToModerators($arNotifyParams); $successfulUserIdList[] = $arRel["USER_ID"]; } $successfulUserIdList = array_unique($successfulUserIdList); if (!empty($successfulUserIdList)) { Integration\Im\Chat\Workgroup::setChatManagers(array( 'group_id' => $groupId, 'user_id' => $successfulUserIdList, 'set' => false )); } if ( $bSuccess && count($arSuccessRelations) <= 0 ) { $APPLICATION->ThrowException(GetMessage("SONET_UR_ERROR_MOD2MEM_INCORRECT_PARAMS"), "MOD2MEM_INCORRECT_PARAMS"); $bSuccess = false; } return $bSuccess; } public static function TransferMember2Moderator($userID, $groupId, $relationIdList): bool { global $APPLICATION, $USER; $userID = (int)$userID; if ($userID <= 0) { $APPLICATION->ThrowException(GetMessage("SONET_UR_EMPTY_USERID"), "ERROR_USERID"); return false; } $groupId = (int)$groupId; if ($groupId <= 0) { $APPLICATION->ThrowException(GetMessage("SONET_UR_EMPTY_GROUPID"), "ERROR_GROUPID"); return false; } if (!is_array($relationIdList)) { return true; } $arGroup = CSocNetGroup::GetByID($groupId); if (!$arGroup || !is_array($arGroup)) { $APPLICATION->ThrowException(GetMessage("SONET_UG_ERROR_NO_GROUP_ID"), "ERROR_NO_GROUP"); return false; } $bSuccess = true; $arSuccessRelations = array(); $relationsToUpdateCount = 0; foreach ($relationIdList as $relationId) { $relationId = (int)$relationId; if ($relationId <= 0) { continue; } $arRelation = CSocNetUserToGroup::GetByID($relationId); if ( !$arRelation || (int)$arRelation["GROUP_ID"] !== $groupId || $arRelation["ROLE"] !== UserToGroupTable::ROLE_USER ) { continue; } $relationsToUpdateCount++; $arFields = array( "ROLE" => UserToGroupTable::ROLE_MODERATOR, "=DATE_UPDATE" => CDatabase::CurrentTimeFunction(), ); if (CSocNetUserToGroup::update($arRelation["ID"], $arFields)) { $arSuccessRelations[] = $arRelation; self::notifyModeratorAdded(array( 'userId' => $userID, 'groupId' => $groupId, 'relationFields' => $arRelation, 'groupFields' => $arGroup )); } else { $errorMessage = ""; if ($e = $APPLICATION->GetException()) { $errorMessage = $e->GetString(); } if ($errorMessage === '') { $errorMessage = Loc::getMessage('SONET_UR_ERROR_CREATE_USER2GROUP'); } $APPLICATION->ThrowException($errorMessage, "ERROR_MEMBER2MOD"); $bSuccess = false; } } if ($relationsToUpdateCount <= 0) { $APPLICATION->ThrowException(GetMessage("SONET_UR_ERROR_MEM2MOD_EMPTY_CORRECT_LIST"), "MOD2MEM_EMPTY_CORRECT_LIST"); return false; } $successfulUserIdList = array(); foreach ($arSuccessRelations as $arRel) { $arNotifyParams = array( "TYPE" => "moderate", "RELATION_ID" => $arRel["ID"], "USER_ID" => $arRel["USER_ID"], "GROUP_ID" => $arRel["GROUP_ID"], "GROUP_NAME" => $arRel["GROUP_NAME"], "EXCLUDE_USERS" => array($arRel["USER_ID"], $USER->GetID()) ); CSocNetUserToGroup::NotifyImToModerators($arNotifyParams); CSocNetSubscription::Set($arRel["USER_ID"], "SG".$arRel["GROUP_ID"], "Y"); $successfulUserIdList[] = $arRel["USER_ID"]; } $successfulUserIdList = array_unique($successfulUserIdList); if (!empty($successfulUserIdList)) { Integration\Im\Chat\Workgroup::setChatManagers(array( 'group_id' => $groupId, 'user_id' => $successfulUserIdList, 'set' => true )); } if ( $bSuccess && count($arSuccessRelations) <= 0 ) { $errorMessage = ""; if ($e = $APPLICATION->GetException()) { $errorMessage = $e->GetString(); } if ($errorMessage === '') { $errorMessage = Loc::getMessage('SONET_UR_ERROR_MEM2MOD_INCORRECT_PARAMS'); } $APPLICATION->ThrowException($errorMessage, "MEM2MOD_INCORRECT_PARAMS"); $bSuccess = false; } return $bSuccess; } public static function BanMember($userID, $groupId, $relationIdList, $currentUserIsAdmin): bool { global $APPLICATION; $userID = (int)$userID; if ($userID <= 0) { $APPLICATION->ThrowException(GetMessage("SONET_UR_EMPTY_USERID"), "ERROR_USERID"); return false; } $groupId = (int)$groupId; if ($groupId <= 0) { $APPLICATION->ThrowException(GetMessage("SONET_UR_EMPTY_GROUPID"), "ERROR_GROUPID"); return false; } if (!is_array($relationIdList)) { return true; } $arGroup = CSocNetGroup::GetByID($groupId); if (!$arGroup || !is_array($arGroup)) { $APPLICATION->ThrowException(GetMessage("SONET_UG_ERROR_NO_GROUP_ID"), "ERROR_NO_GROUP"); return false; } $arUserPerms = CSocNetUserToGroup::InitUserPerms($userID, $arGroup, $currentUserIsAdmin); if (!$arUserPerms["UserCanModifyGroup"] && !$arUserPerms["UserCanModerateGroup"]) { $APPLICATION->ThrowException(GetMessage("SONET_UG_ERROR_NO_PERMS"), "ERROR_NO_PERMS"); return false; } $bSuccess = true; foreach ($relationIdList as $relationId) { $relationId = (int)$relationId; if ($relationId <= 0) { continue; } $arRelation = CSocNetUserToGroup::GetByID($relationId); if (!$arRelation) { continue; } if ( (int)$arRelation["GROUP_ID"] !== $groupId || $arRelation["ROLE"] !== UserToGroupTable::ROLE_USER ) { continue; } $arFields = array( "ROLE" => UserToGroupTable::ROLE_BAN, "=DATE_UPDATE" => CDatabase::CurrentTimeFunction(), ); if (CSocNetUserToGroup::Update($arRelation["ID"], $arFields)) { $arMessageFields = array( "FROM_USER_ID" => $userID, "TO_USER_ID" => $arRelation["USER_ID"], "MESSAGE" => fn (?string $languageId = null) => Loc::getMessage( "SONET_UG_BANMEMBER_MESSAGE", [ "#NAME#" => $arGroup["NAME"] ], $languageId ), "=DATE_CREATE" => CDatabase::CurrentTimeFunction(), "MESSAGE_TYPE" => SONET_MESSAGE_SYSTEM ); CSocNetMessages::Add($arMessageFields); CSocNetSubscription::DeleteEx($arRelation["USER_ID"], "SG".$arRelation["GROUP_ID"]); UserToGroup::addInfoToChat(array( 'group_id' => $groupId, 'user_id' => $arRelation["USER_ID"], 'action' => UserToGroup::CHAT_ACTION_OUT )); } else { $errorMessage = ""; if ($e = $APPLICATION->GetException()) { $errorMessage = $e->GetString(); } if ($errorMessage === '') { $errorMessage = Loc::getMessage('SONET_UR_ERROR_CREATE_USER2GROUP'); } $APPLICATION->ThrowException($errorMessage, "ERROR_BANMEMBER"); $bSuccess = false; } } return $bSuccess; } public static function UnBanMember($userID, $groupId, $relationIdList, $currentUserIsAdmin): bool { global $APPLICATION; $userID = (int)$userID; if ($userID <= 0) { $APPLICATION->ThrowException(GetMessage("SONET_UR_EMPTY_USERID"), "ERROR_USERID"); return false; } $groupId = (int)$groupId; if ($groupId <= 0) { $APPLICATION->ThrowException(GetMessage("SONET_UR_EMPTY_GROUPID"), "ERROR_GROUPID"); return false; } if (!is_array($relationIdList)) { return true; } $arGroup = CSocNetGroup::GetByID($groupId); if (!$arGroup || !is_array($arGroup)) { $APPLICATION->ThrowException(GetMessage("SONET_UG_ERROR_NO_GROUP_ID"), "ERROR_NO_GROUP"); return false; } $arUserPerms = CSocNetUserToGroup::InitUserPerms($userID, $arGroup, $currentUserIsAdmin); if (!$arUserPerms["UserCanModifyGroup"] && !$arUserPerms["UserCanModerateGroup"]) { $APPLICATION->ThrowException(GetMessage("SONET_UG_ERROR_NO_PERMS"), "ERROR_NO_PERMS"); return false; } $bSuccess = true; foreach ($relationIdList as $relationId) { $relationId = (int)$relationId; if ($relationId <= 0) { continue; } $arRelation = CSocNetUserToGroup::GetByID($relationId); if (!$arRelation) { continue; } if ( (int)$arRelation["GROUP_ID"] !== $groupId || $arRelation["ROLE"] !== UserToGroupTable::ROLE_BAN ) { continue; } $arFields = array( "ROLE" => UserToGroupTable::ROLE_USER, "=DATE_UPDATE" => CDatabase::CurrentTimeFunction(), ); if (CSocNetUserToGroup::Update($arRelation["ID"], $arFields)) { CSocNetMessages::Add(array( "FROM_USER_ID" => $userID, "TO_USER_ID" => $arRelation["USER_ID"], "MESSAGE" => fn (?string $languageId = null) => Loc::getMessage( "SONET_UG_UNBANMEMBER_MESSAGE", [ "#NAME#" => $arGroup["NAME"] ], $languageId ), "=DATE_CREATE" => CDatabase::CurrentTimeFunction(), "MESSAGE_TYPE" => SONET_MESSAGE_SYSTEM )); UserToGroup::addInfoToChat(array( 'group_id' => $groupId, 'user_id' => $userID, 'action' => UserToGroup::CHAT_ACTION_IN, 'role' => $arFields['ROLE'] )); } else { $errorMessage = ""; if ($e = $APPLICATION->GetException()) { $errorMessage = $e->GetString(); } if ($errorMessage === '') { $errorMessage = Loc::getMessage('SONET_UR_ERROR_CREATE_USER2GROUP'); } $APPLICATION->ThrowException($errorMessage, "ERROR_UNBANMEMBER"); $bSuccess = false; } } return $bSuccess; } public static function SetOwner($userId, $groupId, $groupFields = [], bool $skipChatMessage = false): bool { global $DB, $APPLICATION, $USER; if (empty($groupFields)) { $groupFields = WorkgroupTable::getList([ 'select' => [ 'TYPE', 'SITE_ID', 'OWNER_ID', 'NAME', ], 'filter' => ['ID' => $groupId], ])->fetch(); } if (empty($groupFields)) { return false; } $errorMessage = ""; $DB->StartTransaction(); // setting relations for the old owner $res = CSocNetUserToGroup::GetList( array(), array( "USER_ID" => $groupFields["OWNER_ID"], "GROUP_ID" => $groupId, ), false, false, array('ID', 'USER_ID') ); if ($existingRelationFields = $res->fetch()) { $role = UserToGroupTable::ROLE_USER; $workgroup = WorkgroupTable::getList([ 'select' => ['SCRUM_MASTER_ID'], 'filter' => ['ID' => $groupId], ])->fetchObject(); if ( $workgroup && $workgroup->getScrumMasterId() === (int)$existingRelationFields['USER_ID'] ) { $role = UserToGroupTable::ROLE_MODERATOR; } $relationFields = array( "ROLE" => $role, "=DATE_UPDATE" => CDatabase::CurrentTimeFunction(), "INITIATED_BY_TYPE" => SONET_INITIATED_BY_USER, "INITIATED_BY_USER_ID" => $USER->GetID(), ); if (!CSocNetUserToGroup::Update($existingRelationFields["ID"], $relationFields)) { if ($e = $APPLICATION->GetException()) { $errorMessage = $e->GetString(); } if ($errorMessage === '') { $errorMessage = Loc::getMessage('SONET_UG_ERROR_CANNOT_UPDATE_CURRENT_OWNER'); } $APPLICATION->ThrowException($errorMessage, "ERROR_UPDATE_USER2GROUP"); $DB->Rollback(); return false; } } CSocNetUserToGroup::__SpeedFileDelete($groupFields["OWNER_ID"]); // setting relations for the new owner $res = CSocNetUserToGroup::GetList( [], [ 'USER_ID' => $userId, 'GROUP_ID' => $groupId, ], false, false, [ 'ID', 'ROLE' ] ); if ($existingRelationFields = $res->Fetch()) { $relationFields = array( "ROLE" => UserToGroupTable::ROLE_OWNER, "=DATE_UPDATE" => CDatabase::CurrentTimeFunction(), "INITIATED_BY_TYPE" => SONET_INITIATED_BY_USER, "INITIATED_BY_USER_ID" => $USER->GetID(), "AUTO_MEMBER" => "N" ); if (!CSocNetUserToGroup::Update($existingRelationFields["ID"], $relationFields)) { if ($e = $APPLICATION->GetException()) { $errorMessage = $e->GetString(); } if ($errorMessage === '') { $errorMessage = Loc::getMessage('SONET_UG_ERROR_CANNOT_UPDATE_NEW_OWNER_RELATION'); } $APPLICATION->ThrowException($errorMessage, "ERROR_UPDATE_USER2GROUP"); $DB->Rollback(); return false; } if (!$skipChatMessage && !in_array($existingRelationFields["ID"], UserToGroupTable::getRolesMember(), true)) { UserToGroup::addInfoToChat([ 'group_id' => $groupId, 'user_id' => $userId, 'action' => UserToGroup::CHAT_ACTION_IN, 'role' => $relationFields['ROLE'], ]); } if (Loader::includeModule('im')) { CIMNotify::deleteByTag('SOCNET|INVITE_GROUP|' . (int)$userId . '|' . (int)$existingRelationFields['ID']); } } else { $relationFields = array( "USER_ID" => $userId, "GROUP_ID" => $groupId, "ROLE" => UserToGroupTable::ROLE_OWNER, "=DATE_CREATE" => CDatabase::CurrentTimeFunction(), "=DATE_UPDATE" => CDatabase::CurrentTimeFunction(), "INITIATED_BY_TYPE" => SONET_INITIATED_BY_USER, "INITIATED_BY_USER_ID" => $USER->GetID(), "MESSAGE" => false, ); if (!CSocNetUserToGroup::Add($relationFields)) { if ($e = $APPLICATION->GetException()) { $errorMessage = $e->GetString(); } if ($errorMessage === '') { $errorMessage = Loc::getMessage('SONET_UG_ERROR_CANNOT_ADD_NEW_OWNER_RELATION'); } $APPLICATION->ThrowException($errorMessage, "ERROR_ADD_USER2GROUP"); $DB->Rollback(); return false; } if (!$skipChatMessage) { UserToGroup::addInfoToChat([ 'group_id' => $groupId, 'user_id' => $userId, 'action' => UserToGroup::CHAT_ACTION_IN, 'role' => $relationFields['ROLE'], ]); } } $GROUP_ID = CSocNetGroup::Update($groupId, array("OWNER_ID" => $userId)); if (!$GROUP_ID || $GROUP_ID <= 0) { if ($e = $APPLICATION->GetException()) { $errorMessage = $e->GetString(); } if ($errorMessage === '') { $errorMessage = Loc::getMessage('SONET_UG_ERROR_CANNOT_UPDATE_GROUP'); } $APPLICATION->ThrowException($errorMessage, "ERROR_UPDATE_GROUP"); $DB->Rollback(); return false; } $bIMIncluded = false; $groupUrl = ""; $groupSiteId = SITE_ID; if (Loader::includeModule('im')) { $bIMIncluded = true; $groupSiteId = CSocNetGroup::GetDefaultSiteId($groupId, $groupFields["SITE_ID"] ?? false); $workgroupsPage = COption::GetOptionString("socialnetwork", "workgroups_page", "/workgroups/", $groupSiteId); $groupUrlTemplate = Path::get('group_path_template', $groupSiteId); $groupUrlTemplate = "#GROUPS_PATH#".mb_substr($groupUrlTemplate, mb_strlen($workgroupsPage)); $groupUrl = str_replace(array("#group_id#", "#GROUP_ID#"), $groupId, $groupUrlTemplate); } // send message to the old owner if ($bIMIncluded) { $arTmp = CSocNetLogTools::ProcessPath( array( "GROUP_URL" => $groupUrl ), $groupFields["OWNER_ID"], $groupSiteId ); $groupUrl = $arTmp["URLS"]["GROUP_URL"]; $serverName = ( mb_strpos($groupUrl, "http://") === 0 || mb_strpos($groupUrl, "https://") === 0 ? "" : $arTmp["SERVER_NAME"] ); $notifyNewOwnerMessageKey = 'SONET_UG_OWNER2MEMBER_MESSAGE'; if (($groupFields['TYPE'] ?? null) === Workgroup\Type::Collab->value) { $notifyNewOwnerMessageKey = 'SONET_UG_OWNER2MEMBER_MESSAGE_COLLAB'; } $messageFields = array( "TO_USER_ID" => $groupFields["OWNER_ID"], "FROM_USER_ID" => $USER->GetID(), "NOTIFY_TYPE" => IM_NOTIFY_FROM, "NOTIFY_MODULE" => "socialnetwork", "NOTIFY_EVENT" => "owner_group", "NOTIFY_TAG" => "SOCNET|OWNER_GROUP|".$groupId, "NOTIFY_MESSAGE" => fn (?string $languageId = null) => Loc::getMessage( $notifyNewOwnerMessageKey, ['#NAME#' => "<a href=\"".$groupUrl."\" class=\"bx-notifier-item-action\">".$groupFields["NAME"]."</a>"], $languageId ) , "NOTIFY_MESSAGE_OUT" => function (?string $languageId = null) use ($groupFields, $serverName, $groupUrl) { $message = Loc::getMessage( "SONET_UG_OWNER2MEMBER_MESSAGE", ["#NAME#" => $groupFields['NAME']], $languageId ); return $message . " (" . $serverName . $groupUrl . ")"; }, ); CIMNotify::Add($messageFields); } // send message to the new owner if ($bIMIncluded) { $arTmp = CSocNetLogTools::ProcessPath( array( "GROUP_URL" => $groupUrl ), $userId, $groupSiteId ); $groupUrl = $arTmp["URLS"]["GROUP_URL"]; if ( mb_strpos($groupUrl, "http://") === 0 || mb_strpos($groupUrl, "https://") === 0 ) { $serverName = ""; } else { $serverName = $arTmp["SERVER_NAME"]; } $notifyOldOwnerMessageKey = 'SONET_UG_MEMBER2OWNER_MESSAGE'; if (($groupFields['TYPE'] ?? null) === Workgroup\Type::Collab->value) { $notifyOldOwnerMessageKey = 'SONET_UG_MEMBER2OWNER_MESSAGE_COLLAB'; } $messageFields = array( "TO_USER_ID" => $userId, "FROM_USER_ID" => $USER->GetID(), "NOTIFY_TYPE" => IM_NOTIFY_FROM, "NOTIFY_MODULE" => "socialnetwork", "NOTIFY_EVENT" => "owner_group", "NOTIFY_TAG" => "SOCNET|OWNER_GROUP|".$groupId, "NOTIFY_MESSAGE" => fn (?string $languageId = null) => Loc::getMessage( $notifyOldOwnerMessageKey, ["#NAME#" => "<a href=\"".$groupUrl."\" class=\"bx-notifier-item-action\">".$groupFields["NAME"]."</a>"], $languageId ) , "NOTIFY_MESSAGE_OUT" => function (?string $languageId = null) use ($groupFields, $serverName, $groupUrl) { $message = Loc::getMessage( "SONET_UG_MEMBER2OWNER_MESSAGE", ["#NAME#" => $groupFields['NAME']], $languageId ); return $message . " (" . $serverName . $groupUrl . ")"; }, ); CIMNotify::Add($messageFields); } $notificationParams = array( "TYPE" => "owner", "RELATION_ID" => $existingRelationFields["ID"] ?? null, "USER_ID" => $userId, "GROUP_ID" => $groupId, "GROUP_NAME" => htmlspecialcharsbx($groupFields["NAME"]), "EXCLUDE_USERS" => array($userId, $groupFields["OWNER_ID"], $USER->GetID()) ); CSocNetUserToGroup::NotifyImToModerators($notificationParams); CSocNetSubscription::Set($userId, "SG".$groupId, "Y"); $DB->Commit(); return true; } public static function DeleteRelation($userId, $groupId): bool { global $APPLICATION; $userId = (int)$userId; if ($userId <= 0) { $APPLICATION->ThrowException(GetMessage("SONET_UR_EMPTY_USERID"), "ERROR_USER_ID"); return false; } $groupId = (int)$groupId; if ($groupId <= 0) { $APPLICATION->ThrowException(GetMessage("SONET_UR_EMPTY_GROUPID"), "ERROR_GROUPID"); return false; } $res = CSocNetUserToGroup::GetList( array(), array( "GROUP_ID" => $groupId, "USER_ID" => $userId, ), false, false, [ 'ID', 'USER_ID', 'ROLE', 'GROUP_VISIBLE', 'GROUP_NAME', 'GROUP_SCRUM_MASTER_ID' ] ); if ($relationFields = $res->Fetch()) { if (!in_array($relationFields["ROLE"], [ UserToGroupTable::ROLE_USER, UserToGroupTable::ROLE_MODERATOR, ], true)) { return false; } if ((int)$relationFields['USER_ID'] === (int)$relationFields['GROUP_SCRUM_MASTER_ID']) { return false; } if (!empty($relationFields['GROUP_NAME'])) { $relationFields['GROUP_NAME'] = Emoji::decode($relationFields['GROUP_NAME']); } if (CSocNetUserToGroup::Delete($relationFields["ID"])) { CSocNetSubscription::DeleteEx($userId, "SG".$groupId); if (ModuleManager::isModuleInstalled('im')) { $chatNotificationResult = UserToGroup::addInfoToChat(array( 'group_id' => $groupId, 'user_id' => $userId, 'action' => UserToGroup::CHAT_ACTION_OUT )); if (!$chatNotificationResult) { CSocNetUserToGroup::notifyImToModerators(array( "TYPE" => "unjoin", "RELATION_ID" => $relationFields["ID"], "USER_ID" => $userId, "GROUP_ID" => $groupId, "GROUP_NAME" => $relationFields["GROUP_NAME"] )); } } } else { $errorMessage = ""; if ($e = $APPLICATION->GetException()) { $errorMessage = $e->GetString(); } if ($errorMessage === '') { $errorMessage = Loc::getMessage('SONET_UR_ERROR_CREATE_USER2GROUP'); } $APPLICATION->ThrowException($errorMessage, "ERROR_DELETE_RELATION"); return false; } } else { $APPLICATION->ThrowException(GetMessage("SONET_NO_USER2GROUP"), "ERROR_NO_MEMBER_REQUEST"); return false; } CSocNetUserToGroup::__SpeedFileCheckMessages($userId); return true; } public static function InitUserPerms($userId, $groupFields, $isCurrentUserAdmin) { global $arSocNetAllowedInitiatePerms; global $arSocNetAllowedSpamPerms; $arReturn = array(); $userId = (int)$userId; $groupId = (int)$groupFields["ID"]; $groupOwnerId = (int)$groupFields["OWNER_ID"]; $groupInitiatePerms = Trim($groupFields["INITIATE_PERMS"]); $groupVisible = Trim($groupFields["VISIBLE"]); $groupOpened = Trim($groupFields["OPENED"]); $groupSpamPerms = Trim(($groupFields["SPAM_PERMS"] ?? '')); if ($groupId <= 0 || $groupOwnerId <= 0 || !in_array($groupInitiatePerms, $arSocNetAllowedInitiatePerms)) { return false; } $arReturn["Operations"] = []; if (!in_array($groupSpamPerms, $arSocNetAllowedSpamPerms)) { $groupSpamPerms = "K"; } // UserRole - User role in group. False if user is not group member. // UserIsMember - True in user is group member. // UserIsAuto - True in user is group auto member. // UserIsOwner - True if user is group owner. // UserCanInitiate - True if user can invite friends to group. // UserCanViewGroup - True if user can view group. // UserCanAutoJoinGroup - True if user can join group automatically. // UserCanModifyGroup - True if user can modify group. // UserCanModerateGroup - True if user can moderate group. if ($userId <= 0) { $arReturn["UserRole"] = false; $arReturn["UserIsMember"] = false; $arReturn["UserIsAutoMember"] = false; $arReturn["UserIsOwner"] = false; $arReturn['UserIsScrumMaster'] = false; $arReturn["UserCanInitiate"] = false; $arReturn["UserCanProcessRequestsIn"] = false; $arReturn["UserCanViewGroup"] = ($groupVisible === "Y"); $arReturn["UserCanAutoJoinGroup"] = false; $arReturn["UserCanModifyGroup"] = false; $arReturn["UserCanModerateGroup"] = false; $arReturn["UserCanSpamGroup"] = false; $arReturn["InitiatedByType"] = false; $arReturn["InitiatedByUserId"] = false; $arReturn["Operations"]["viewsystemevents"] = false; } else { if (!isset($groupFields['SCRUM'])) { $group = Workgroup::getById($groupFields['ID']); $groupFields['SCRUM'] = ($group && $group->isScrumProject() ? 'Y' : 'N'); } if (!isset($groupFields['SCRUM_MASTER_ID'])) { $group = Workgroup::getById($groupFields['ID']); $groupFields['SCRUM_MASTER_ID'] = ($group ? $group->getScrumMaster() : 0); } $arUserRoleExtended = CSocNetUserToGroup::GetUserRole($userId, $groupId, true); $arReturn["UserRole"] = $arUserRoleExtended["ROLE"]; $arReturn["UserIsMember"] = ( $arReturn["UserRole"] && in_array($arReturn["UserRole"], UserToGroupTable::getRolesMember(), true) ); $arReturn["UserIsAutoMember"] = ( $arReturn["UserIsMember"] && $arUserRoleExtended["AUTO_MEMBER"] === "Y" ); $arReturn["InitiatedByType"] = false; $arReturn["InitiatedByUserId"] = false; if ($arReturn["UserRole"] === UserToGroupTable::ROLE_REQUEST) { $dbRelation = CSocNetUserToGroup::GetList( [], [ 'USER_ID' => $userId, 'GROUP_ID' => $groupId ], false, false, [ 'INITIATED_BY_TYPE', 'INITIATED_BY_USER_ID' ] ); if ($arRelation = $dbRelation->Fetch()) { $arReturn["InitiatedByType"] = $arRelation["INITIATED_BY_TYPE"]; $arReturn["InitiatedByUserId"] = (int)$arRelation['INITIATED_BY_USER_ID']; } } $arReturn["UserIsOwner"] = ($userId === $groupOwnerId); $arReturn['UserIsScrumMaster'] = ( $groupFields['SCRUM'] === 'Y' && (int)$groupFields['SCRUM_MASTER_ID'] === $userId ); if ($isCurrentUserAdmin) { $arReturn["UserCanInitiate"] = true; $arReturn["UserCanProcessRequestsIn"] = true; $arReturn["UserCanViewGroup"] = true; $arReturn["UserCanAutoJoinGroup"] = true; $arReturn["UserCanModifyGroup"] = true; $arReturn["UserCanModerateGroup"] = true; $arReturn["UserCanSpamGroup"] = true; $arReturn["Operations"]["viewsystemevents"] = true; } elseif ($arReturn["UserIsMember"]) { $arReturn["UserCanInitiate"] = ( ( $groupInitiatePerms === UserToGroupTable::ROLE_OWNER && $arReturn['UserIsOwner'] ) || ( $groupInitiatePerms === UserToGroupTable::ROLE_MODERATOR && in_array($arReturn['UserRole'], [ UserToGroupTable::ROLE_OWNER, UserToGroupTable::ROLE_MODERATOR, ], true) ) || ($groupInitiatePerms === UserToGroupTable::ROLE_USER) ); $arReturn['UserCanProcessRequestsIn'] = ( $arReturn['UserCanInitiate'] && in_array($arReturn['UserRole'], [ UserToGroupTable::ROLE_OWNER, UserToGroupTable::ROLE_MODERATOR, ], true) ); $arReturn["UserCanViewGroup"] = true; $arReturn["UserCanAutoJoinGroup"] = false; $arReturn["UserCanModifyGroup"] = $arReturn["UserIsOwner"]; if ( !$arReturn['UserCanModifyGroup'] && $groupFields['SCRUM'] === 'Y' ) { if (!isset($groupFields['SCRUM_MASTER_ID'])) { $group = Workgroup::getById($groupFields['ID']); $groupFields['SCRUM_MASTER_ID'] = ($group ? $group->getScrumMaster() : 0); } $arReturn['UserCanModifyGroup'] = ((int)$groupFields['SCRUM_MASTER_ID'] === $userId); } $arReturn["UserCanModerateGroup"] = (in_array($arReturn['UserRole'], [ UserToGroupTable::ROLE_OWNER, UserToGroupTable::ROLE_MODERATOR, ], true)); $arReturn['UserCanSpamGroup'] = ( ( $groupSpamPerms === UserToGroupTable::ROLE_OWNER && $arReturn['UserIsOwner'] ) || ( $groupSpamPerms === UserToGroupTable::ROLE_MODERATOR && in_array($arReturn["UserRole"], [ UserToGroupTable::ROLE_OWNER, UserToGroupTable::ROLE_MODERATOR, ], true) ) || $groupSpamPerms === UserToGroupTable::ROLE_USER || $groupSpamPerms === SONET_ROLES_ALL ); $arReturn["Operations"]["viewsystemevents"] = true; } else { $arReturn["UserCanInitiate"] = false; $arReturn["UserCanViewGroup"] = ($groupVisible === "Y"); $arReturn["UserCanAutoJoinGroup"] = ($arReturn["UserCanViewGroup"] && ($groupOpened === "Y")); $arReturn["UserCanModifyGroup"] = false; $arReturn["UserCanModerateGroup"] = false; $arReturn["UserCanSpamGroup"] = ($groupSpamPerms === SONET_ROLES_ALL); $arReturn["Operations"]["viewsystemevents"] = false; } } if (Loader::includeModule('extranet') && CExtranet::IsExtranetSite()) { $arReturn["UserCanSpamGroup"] = true; } if (!CBXFeatures::IsFeatureEnabled("WebMessenger")) { $arReturn["UserCanSpamGroup"] = false; } return $arReturn; } public static function __SpeedFileCheckMessages($userID) { global $DB; $userID = (int)$userID; if ($userID <= 0) { return; } $cnt = 0; $dbResult = $DB->Query( "SELECT COUNT(ID) as CNT ". "FROM b_sonet_user2group ". "WHERE USER_ID = ".$userID." ". " AND ROLE = '".$DB->ForSql(UserToGroupTable::ROLE_REQUEST, 1)."' ". " AND INITIATED_BY_TYPE = '".$DB->ForSql(SONET_INITIATED_BY_GROUP, 1)."' " ); if ($arResult = $dbResult->Fetch()) { $cnt = (int)$arResult["CNT"]; } if ($cnt > 0) { CSocNetUserToGroup::__SpeedFileCreate($userID); } else { CSocNetUserToGroup::__SpeedFileDelete($userID); } } public static function __SpeedFileCreate($userID) { global $CACHE_MANAGER; $userID = (int)$userID; if ($userID <= 0) { return; } if ($CACHE_MANAGER->Read(86400*30, "socnet_cg_".$userID)) { $CACHE_MANAGER->Clean("socnet_cg_".$userID); } } public static function __SpeedFileDelete($userID) { global $CACHE_MANAGER; $userID = (int)$userID; if ($userID <= 0) { return; } if (!$CACHE_MANAGER->Read(86400*30, "socnet_cg_".$userID)) { $CACHE_MANAGER->Set("socnet_cg_".$userID, true); } } public static function SpeedFileExists($userID): bool { global $CACHE_MANAGER; $userID = (int)$userID; if ($userID <= 0) { return false; } return (!$CACHE_MANAGER->Read(86400*30, "socnet_cg_".$userID)); } /* Module IM callback */ public static function OnBeforeConfirmNotify($module, $tag, $value) { global $USER; if ($module === "socialnetwork") { $arTag = explode("|", $tag); if ( count($arTag) === 4 && $arTag[1] === 'INVITE_GROUP' ) { if ($value === 'Y') { self::UserConfirmRequestToBeMember($arTag[2], $arTag[3]); } else { self::UserRejectRequestToBeMember($arTag[2], $arTag[3]); } return true; } if ( count($arTag) === 6 && $arTag[1] === "REQUEST_GROUP" ) { if ($value === "Y") { self::ConfirmRequestToBeMember($USER->GetID(), $arTag[3], array($arTag[4])); } else { self::RejectRequestToBeMember($USER->GetID(), $arTag[3], array($arTag[4])); } if (Loader::includeModule('im')) { CIMNotify::DeleteBySubTag("SOCNET|REQUEST_GROUP|".$arTag[2]."|".$arTag[3]."|".$arTag[4]); } return true; } } return null; } public static function NotifyImToModerators($arNotifyParams): void { if (!Loader::includeModule('im')) { return; } if ( !is_array($arNotifyParams) || !isset( $arNotifyParams["TYPE"], $arNotifyParams["USER_ID"], $arNotifyParams["GROUP_ID"], $arNotifyParams["RELATION_ID"], $arNotifyParams["GROUP_NAME"] ) || (int)$arNotifyParams["USER_ID"] <= 0 || (int)$arNotifyParams["GROUP_ID"] <= 0 || (int)$arNotifyParams["RELATION_ID"] <= 0 || (string)$arNotifyParams["GROUP_NAME"] === '' || !in_array($arNotifyParams["TYPE"], [ "join", "unjoin", "exclude", "moderate", "unmoderate", "owner" ], true) ) { return; } $fromUserId = false; $messageCode = false; $schemaCode = false; $notifyTag = false; switch ($arNotifyParams["TYPE"]) { case "join": $fromUserId = $arNotifyParams["USER_ID"]; $messageCode = "SONET_UG_IM_JOIN"; $schemaCode = "inout_group"; $notifyTag = "INOUT_GROUP"; break; case "unjoin": $fromUserId = $arNotifyParams["USER_ID"]; $messageCode = "SONET_UG_IM_UNJOIN"; $schemaCode = "inout_group"; $notifyTag = "INOUT_GROUP"; break; case "exclude": $fromUserId = $arNotifyParams["USER_ID"]; $messageCode = "SONET_UG_IM_EXCLUDE"; $schemaCode = "inout_group"; $notifyTag = "INOUT_GROUP"; break; case "moderate": $fromUserId = $arNotifyParams["USER_ID"]; $messageCode = "SONET_UG_IM_MODERATE"; $schemaCode = "moderators_group"; $notifyTag = "MOD_GROUP"; break; case "unmoderate": $fromUserId = $arNotifyParams["USER_ID"]; $messageCode = "SONET_UG_IM_UNMODERATE"; $schemaCode = "moderators_group"; $notifyTag = "MOD_GROUP"; break; case "owner": $fromUserId = $arNotifyParams["USER_ID"]; $messageCode = "SONET_UG_IM_OWNER"; $schemaCode = "owner_group"; $notifyTag = "OWNER_GROUP"; break; default: } $gender_suffix = ""; $rsUser = CUser::GetByID($arNotifyParams["USER_ID"]); if ($arUser = $rsUser->Fetch()) { switch ($arUser["PERSONAL_GENDER"]) { case "M": $gender_suffix = "_M"; break; case "F": $gender_suffix = "_F"; break; default: $gender_suffix = ""; } } $arToUserID = []; $rsUserToGroup = CSocNetUserToGroup::GetList( array(), array( "GROUP_ID" => $arNotifyParams["GROUP_ID"], "USER_ACTIVE" => "Y", "<=ROLE" => UserToGroupTable::ROLE_MODERATOR, ), false, false, array("USER_ID") ); while ($arUserToGroup = $rsUserToGroup->Fetch()) { $arToUserID[] = (int)$arUserToGroup["USER_ID"]; } $arMessageFields = array( "MESSAGE_TYPE" => IM_MESSAGE_SYSTEM, "FROM_USER_ID" => $fromUserId, "NOTIFY_TYPE" => IM_NOTIFY_FROM, "NOTIFY_MODULE" => "socialnetwork", "NOTIFY_EVENT" => $schemaCode, "NOTIFY_TAG" => "SOCNET|" . $notifyTag . "|" . (int)$arNotifyParams["USER_ID"] . "|" . (int)$arNotifyParams["GROUP_ID"] . "|" . (int)$arNotifyParams["RELATION_ID"], ); $groups_path = COption::GetOptionString("socialnetwork", "workgroups_page", SITE_DIR."workgroups/"); $group_url_template = str_replace( $groups_path, "#GROUPS_PATH#", Path::get('group_path_template') ); $groupUrl = str_replace( "#group_id#", $arNotifyParams["GROUP_ID"], $group_url_template ); foreach ($arToUserID as $to_user_id) { if ( $to_user_id === (int)$fromUserId || ( is_array($arNotifyParams["EXCLUDE_USERS"] ?? null) && in_array($to_user_id, $arNotifyParams["EXCLUDE_USERS"]) ) ) { continue; } $arMessageFields["TO_USER_ID"] = $to_user_id; $arTmp = CSocNetLogTools::ProcessPath( array( "GROUP_PAGE" => $groupUrl ), $to_user_id, SITE_ID ); $arMessageFields["NOTIFY_MESSAGE"] = fn (?string $languageId = null) => Loc::getMessage( $messageCode.$gender_suffix, [ "#group_name#" => "<a href=\"".$arTmp["URLS"]["GROUP_PAGE"]."\" class=\"bx-notifier-item-action\">".$arNotifyParams["GROUP_NAME"]."</a>", ], $languageId ); $arMessageFields["NOTIFY_MESSAGE_OUT"] = fn (?string $languageId = null) => Loc::getMessage( $messageCode.$gender_suffix, [ "#group_name#" => $arNotifyParams["GROUP_NAME"], ], $languageId ) ." (".$arTmp["SERVER_NAME"].$arTmp["URLS"]["GROUP_PAGE"].")" ; CIMNotify::Add($arMessageFields); } } public static function getMessage($message) { return Loc::getMessage($message); } public static function notifyModeratorAdded($params): void { static $groupCache = array(); $userId = (!empty($params['userId']) ? (int)$params['userId'] : 0); $relationFields = (!empty($params['relationFields']) && is_array($params['relationFields']) ? $params['relationFields'] : array()); $groupFields = (!empty($params['groupFields']) && is_array($params['groupFields']) ? $params['groupFields'] : array()); $groupId = ( !empty($params['groupId']) ? (int)$params['groupId'] : (!empty($groupFields['ID']) ? (int)$groupFields['ID'] : 0) ); $relationId = ( !empty($params['relationId']) ? (int)$params['relationId'] : (!empty($relationFields['ID']) ? (int)$relationFields['ID'] : 0) ); if ( empty($groupFields) && $groupId > 0 ) { if (isset($groupCache[$groupId])) { $groupFields = $groupCache[$groupId]; } else { $res = WorkgroupTable::getList(array( 'filter' => array( '=ID' => $groupId ), 'select' => array('ID', 'NAME', 'SITE_ID') )); $groupFields = $groupCache[$groupId] = $res->fetch(); } } if ( empty($relationFields) && $relationId > 0 ) { $res = UserToGroupTable::getList(array( 'filter' => array( '=ID' => $relationId ), 'select' => array('ID', 'USER_ID') )); $relationFields = $res->fetch(); } if ( $groupId <= 0 || empty($relationFields) || empty($relationFields['ID']) || empty($relationFields['USER_ID']) || empty($groupFields) || !Loader::includeModule('im') ) { return; } $groupSiteId = CSocNetGroup::getDefaultSiteId($groupId, $groupFields["SITE_ID"] ?? false); $workgroupsPage = COption::getOptionString("socialnetwork", "workgroups_page", "/workgroups/", SITE_ID); $groupUrlTemplate = Path::get('group_path_template'); $groupUrlTemplate = "#GROUPS_PATH#".mb_substr($groupUrlTemplate, mb_strlen($workgroupsPage)); $groupUrl = str_replace(array("#group_id#", "#GROUP_ID#"), $groupId, $groupUrlTemplate); $arTmp = CSocNetLogTools::processPath( array( "GROUP_URL" => $groupUrl ), $relationFields["USER_ID"], $groupSiteId ); $groupUrl = $arTmp["URLS"]["GROUP_URL"]; $serverName = ( mb_strpos($groupUrl, "http://") === 0 || mb_strpos($groupUrl, "https://") === 0 ? "" : $arTmp["SERVER_NAME"] ); $domainName = ( mb_strpos($groupUrl, "http://") === 0 || mb_strpos($groupUrl, "https://") === 0 ? "" : ( isset($arTmp["DOMAIN"]) && !empty($arTmp["DOMAIN"]) ? "//".$arTmp["DOMAIN"] : "" ) ); $arMessageFields = array( "TO_USER_ID" => $relationFields["USER_ID"], "FROM_USER_ID" => $userId, "NOTIFY_TYPE" => IM_NOTIFY_FROM, "NOTIFY_MODULE" => "socialnetwork", "NOTIFY_EVENT" => "moderators_group", "NOTIFY_TAG" => "SOCNET|MOD_GROUP|" . $userId . "|".$groupId."|".$relationFields["ID"]."|".$relationFields["USER_ID"], "NOTIFY_MESSAGE" => fn (?string $languageId = null) => Loc::getMessage( "SONET_UG_MEMBER2MOD_MESSAGE", ['#NAME#' => "<a href=\"".$domainName.$groupUrl."\" class=\"bx-notifier-item-action\">".$groupFields["NAME"]."</a>"], $languageId ) , "NOTIFY_MESSAGE_OUT" => fn (?string $languageId = null) => Loc::getMessage( "SONET_UG_MEMBER2MOD_MESSAGE", ['#NAME#' => $groupFields["NAME"]], $languageId ) ." (".$serverName.$groupUrl.")" ); CIMNotify::add($arMessageFields); } protected static function delayJob(callable $job): void { \Bitrix\Main\Application::getInstance()->addBackgroundJob($job, [], static::EVENTS_JOB_PRIORITY); } }