Server IP : 85.193.89.191 / Your IP : 13.59.58.18 Web Server : Apache System : Linux 956367-cx40159.tmweb.ru 3.10.0-1160.105.1.el7.x86_64 #1 SMP Thu Dec 7 15:39:45 UTC 2023 x86_64 User : bitrix ( 600) PHP Version : 8.1.27 Disable Function : NONE MySQL : OFF | cURL : OFF | WGET : ON | Perl : ON | Python : ON | Sudo : ON | Pkexec : ON Directory : /home/bitrix/www/bitrix/modules/socialnetwork/lib/ |
Upload File : |
<?php namespace Bitrix\Socialnetwork; use Bitrix\Blog\Item\Post; use Bitrix\Crm\Activity\Provider\Tasks\Task; use Bitrix\Main\Component\ParameterSigner; use Bitrix\Disk\Driver; use Bitrix\Main\Loader; use Bitrix\Main\ModuleManager; use Bitrix\Main; use Bitrix\Main\Localization\Loc; use Bitrix\Main\Config\Option; use Bitrix\Main\EventManager; use Bitrix\Main\Security\Sign\BadSignatureException; use Bitrix\Main\Update\Stepper; use Bitrix\Main\UrlPreview\UrlPreview; use Bitrix\Socialnetwork\Item\Log; use Bitrix\Main\DB\SqlExpression; use Bitrix\Main\Application; use Bitrix\Disk\Uf\FileUserType; use Bitrix\Disk\AttachedObject; use Bitrix\Disk\File; use Bitrix\Disk\TypeFile; use Bitrix\Socialnetwork\Helper\Mention; use Bitrix\Main\Web\Json; use Bitrix\Main\ArgumentException; Loc::loadMessages(__FILE__); class ComponentHelper { protected static $postsCache = []; protected static $commentsCache = []; protected static $commentListsCache = []; protected static $commentCountCache = []; protected static $authorsCache = []; protected static $destinationsCache = []; /** * Returns data of a blog post * * @param int $postId Blog Post Id. * @param string $languageId 2-char language Id. * @return array|bool|false|mixed|null * @throws Main\LoaderException * @throws Main\SystemException */ public static function getBlogPostData($postId, $languageId) { global $USER_FIELD_MANAGER; if (isset(self::$postsCache[$postId])) { $result = self::$postsCache[$postId]; } else { if (!Loader::includeModule('blog')) { throw new Main\SystemException("Could not load 'blog' module."); } $res = \CBlogPost::getList( [], [ "ID" => $postId ], false, false, [ 'ID', 'BLOG_GROUP_ID', 'BLOG_GROUP_SITE_ID', 'BLOG_ID', 'PUBLISH_STATUS', 'TITLE', 'AUTHOR_ID', 'ENABLE_COMMENTS', 'NUM_COMMENTS', 'VIEWS', 'CODE', 'MICRO', 'DETAIL_TEXT', 'DATE_PUBLISH', 'CATEGORY_ID', 'HAS_SOCNET_ALL', 'HAS_TAGS', 'HAS_IMAGES', 'HAS_PROPS', 'HAS_COMMENT_IMAGES' ] ); if ($result = $res->fetch()) { if (!empty($result['DETAIL_TEXT'])) { $result['DETAIL_TEXT'] = \Bitrix\Main\Text\Emoji::decode($result['DETAIL_TEXT']); } $result["ATTACHMENTS"] = []; if($result["HAS_PROPS"] !== "N") { $userFields = $USER_FIELD_MANAGER->getUserFields("BLOG_POST", $postId, $languageId); $postUf = [ 'UF_BLOG_POST_FILE' ]; foreach ($userFields as $fieldName => $userField) { if (!in_array($fieldName, $postUf)) { unset($userFields[$fieldName]); } } if ( !empty($userFields["UF_BLOG_POST_FILE"]) && !empty($userFields["UF_BLOG_POST_FILE"]["VALUE"]) ) { $result["ATTACHMENTS"] = self::getAttachmentsData($userFields["UF_BLOG_POST_FILE"]["VALUE"], $result["BLOG_GROUP_SITE_ID"]); } } $result["DETAIL_TEXT"] = self::convertDiskFileBBCode( $result["DETAIL_TEXT"], 'BLOG_POST', $postId, $result["AUTHOR_ID"], $result["ATTACHMENTS"] ); $result["DETAIL_TEXT_FORMATTED"] = preg_replace( [ '|\[DISK\sFILE\sID=[n]*\d+\]|', '|\[DOCUMENT\sID=[n]*\d+\]|' ], '', $result["DETAIL_TEXT"] ); $result['DETAIL_TEXT_FORMATTED'] = Mention::clear($result['DETAIL_TEXT_FORMATTED']); $p = new \blogTextParser(); $p->arUserfields = []; $images = []; $allow = [ 'IMAGE' => 'Y' ]; $parserParameters = []; $result["DETAIL_TEXT_FORMATTED"] = $p->convert($result["DETAIL_TEXT_FORMATTED"], false, $images, $allow, $parserParameters); $title = ( $result["MICRO"] === "Y" ? \blogTextParser::killAllTags($result["DETAIL_TEXT_FORMATTED"]) : htmlspecialcharsEx($result["TITLE"]) ); $title = preg_replace( '|\[MAIL\sDISK\sFILE\sID=[n]*\d+\]|', '', $title ); $title = str_replace([ "\r\n", "\n", "\r" ], " ", $title); $result["TITLE_FORMATTED"] = \TruncateText($title, 100); $result["DATE_PUBLISH_FORMATTED"] = self::formatDateTimeToGMT($result['DATE_PUBLISH'], $result['AUTHOR_ID']); } self::$postsCache[$postId] = $result; } return $result; } /** * Returns data of blog post destinations * * @param int $postId Blog Post Id. * @return array * @throws Main\LoaderException * @throws Main\SystemException */ public static function getBlogPostDestinations($postId) { if (isset(self::$destinationsCache[$postId])) { $result = self::$destinationsCache[$postId]; } else { $result = []; if (!Loader::includeModule('blog')) { throw new Main\SystemException("Could not load 'blog' module."); } $sonetPermission = \CBlogPost::getSocnetPermsName($postId); if (!empty($sonetPermission)) { foreach ($sonetPermission as $typeCode => $type) { foreach ($type as $destination) { $name = false; if ($typeCode === "SG") { if ($sonetGroup = \CSocNetGroup::getByID($destination["ENTITY_ID"])) { $name = $sonetGroup["NAME"]; } } elseif ($typeCode === "U") { if(in_array("US" . $destination["ENTITY_ID"], $destination["ENTITY"], true)) { $name = "#ALL#"; Loader::includeModule('intranet'); } else { $name = \CUser::formatName( \CSite::getNameFormat(false), [ "NAME" => $destination["~U_NAME"], "LAST_NAME" => $destination["~U_LAST_NAME"], "SECOND_NAME" => $destination["~U_SECOND_NAME"], "LOGIN" => $destination["~U_LOGIN"] ], true ); } } elseif ($typeCode === "DR") { $name = $destination["EL_NAME"]; } if ($name) { $result[] = $name; } } } } self::$destinationsCache[$postId] = $result; } return $result; } /** * Returns data of a blog post/comment author * * @param int $authorId User Id. * @param array $params Format parameters (avatar size etc). * @return array * @throws Main\LoaderException * @throws Main\SystemException */ public static function getBlogAuthorData($authorId, $params): array { if (isset(self::$authorsCache[$authorId])) { $result = self::$authorsCache[$authorId]; } else { if (!Loader::includeModule('blog')) { throw new Main\SystemException("Could not load 'blog' module."); } $result = \CBlogUser::getUserInfo( (int)$authorId, '', [ "AVATAR_SIZE" => ( isset($params["AVATAR_SIZE"]) && (int)$params["AVATAR_SIZE"] > 0 ? (int)$params["AVATAR_SIZE"] : false ), "AVATAR_SIZE_COMMENT" => ( isset($params["AVATAR_SIZE_COMMENT"]) && (int)$params["AVATAR_SIZE_COMMENT"] > 0 ? (int)$params["AVATAR_SIZE_COMMENT"] : false ), "RESIZE_IMMEDIATE" => "Y" ] ); $result["NAME_FORMATTED"] = \CUser::formatName( \CSite::getNameFormat(false), [ "NAME" => $result["~NAME"], "LAST_NAME" => $result["~LAST_NAME"], "SECOND_NAME" => $result["~SECOND_NAME"], "LOGIN" => $result["~LOGIN"] ], true ); self::$authorsCache[$authorId] = $result; } return $result; } /** * Returns full list of blog post comments * * @param int $postId Blog Post Id. * @param array $params Additional paramaters. * @param string $languageId Language Id (2-char). * @param array &$authorIdList List of User Ids. * @return array * @throws Main\LoaderException * @throws Main\SystemException */ public static function getBlogCommentListData($postId, $params, $languageId, &$authorIdList = []): array { if (isset(self::$commentListsCache[$postId])) { $result = self::$commentListsCache[$postId]; } else { $result = []; if (!Loader::includeModule('blog')) { throw new Main\SystemException("Could not load 'blog' module."); } $p = new \blogTextParser(); $selectedFields = [ 'ID', 'BLOG_GROUP_ID', 'BLOG_GROUP_SITE_ID', 'BLOG_ID', 'POST_ID', 'AUTHOR_ID', 'AUTHOR_NAME', 'AUTHOR_EMAIL', 'POST_TEXT', 'DATE_CREATE', 'PUBLISH_STATUS', 'HAS_PROPS', 'SHARE_DEST' ]; $connection = Application::getConnection(); if ($connection instanceof \Bitrix\Main\DB\MysqlCommonConnection) { $selectedFields[] = "DATE_CREATE_TS"; } $res = \CBlogComment::getList( [ 'ID' => 'DESC' ], [ "PUBLISH_STATUS" => BLOG_PUBLISH_STATUS_PUBLISH, "POST_ID" => $postId ], false, [ "nTopCount" => $params["COMMENTS_COUNT"] ], $selectedFields ); while ($comment = $res->fetch()) { self::processCommentData($comment, $languageId, $p, [ "MAIL" => (isset($params["MAIL"]) && $params["MAIL"] === "Y" ? "Y" : "N") ]); $result[] = $comment; if (!in_array((int)$comment["AUTHOR_ID"], $authorIdList, true)) { $authorIdList[] = (int)$comment["AUTHOR_ID"]; } } if (!empty($result)) { $result = array_reverse($result); } self::$commentListsCache[$postId] = $result; } return $result; } /** * Returns a number of blog post comments * * @param int $postId Blog Post Id. * @return bool|int * @throws Main\LoaderException * @throws Main\SystemException */ public static function getBlogCommentListCount($postId) { if (isset(self::$commentCountCache[$postId])) { $result = self::$commentCountCache[$postId]; } else { if (!Loader::includeModule('blog')) { throw new Main\SystemException("Could not load 'blog' module."); } $selectedFields = [ 'ID' ]; $result = \CBlogComment::getList( [ 'ID' => 'DESC' ], [ "PUBLISH_STATUS" => BLOG_PUBLISH_STATUS_PUBLISH, "POST_ID" => $postId, ], [], // count only false, $selectedFields ); self::$commentCountCache[$postId] = $result; } return $result; } /** * Returns data of a blog comment * * @param int $commentId Comment Id. * @param string $languageId Language id (2-chars). * @return array|bool|false|mixed|null */ public static function getBlogCommentData($commentId, $languageId) { $result = []; if (isset(self::$commentsCache[$commentId])) { $result = self::$commentsCache[$commentId]; } else { $selectedFields = [ "ID", "BLOG_GROUP_ID", "BLOG_GROUP_SITE_ID", "BLOG_ID", "POST_ID", "AUTHOR_ID", "AUTHOR_NAME", "AUTHOR_EMAIL", "POST_TEXT", "DATE_CREATE", "PUBLISH_STATUS", "HAS_PROPS", "SHARE_DEST" ]; $connection = Application::getConnection(); if ($connection instanceof \Bitrix\Main\DB\MysqlCommonConnection) { $selectedFields[] = "DATE_CREATE_TS"; } $res = \CBlogComment::getList( [], [ "ID" => $commentId ], false, false, $selectedFields ); if ($comment = $res->fetch()) { $p = new \blogTextParser(); self::processCommentData($comment, $languageId, $p); $result = $comment; } self::$commentsCache[$commentId] = $result; } return $result; } /** * Processes comment data, rendering formatted text and date * * @param array $comment Comment fields set. * @param string $languageId Language Id (2-chars). * @param \blogTextParser $p TextParser object. */ private static function processCommentData(&$comment, $languageId, $p, $params = []): void { global $USER_FIELD_MANAGER; $isMail = ( is_array($params) && isset($params["MAIL"]) && $params["MAIL"] === 'Y' ); $comment["ATTACHMENTS"] = $comment["PROPS"] = []; if ($commentAuxProvider = \Bitrix\Socialnetwork\CommentAux\Base::findProvider( $comment, [ "mobile" => (isset($params["MOBILE"]) && $params["MOBILE"] === "Y"), "mail" => (isset($params["MAIL"]) && $params["MAIL"] === "Y"), "cache" => true ] )) { $comment["POST_TEXT_FORMATTED"] = $commentAuxProvider->getText(); $arComment["AUX_TYPE"] = $commentAuxProvider->getType(); } else { if($comment["HAS_PROPS"] !== "N") { $userFields = $comment["PROPS"] = $USER_FIELD_MANAGER->getUserFields("BLOG_COMMENT", $comment["ID"], $languageId); $commentUf = [ 'UF_BLOG_COMMENT_FILE' ]; foreach ($userFields as $fieldName => $userField) { if (!in_array($fieldName, $commentUf, true)) { unset($userFields[$fieldName]); } } if ( !empty($userFields["UF_BLOG_COMMENT_FILE"]) && !empty($userFields["UF_BLOG_COMMENT_FILE"]["VALUE"]) ) { $comment["ATTACHMENTS"] = self::getAttachmentsData($userFields["UF_BLOG_COMMENT_FILE"]["VALUE"], $comment["BLOG_GROUP_SITE_ID"]); } if ( $isMail && isset($comment["PROPS"]["UF_BLOG_COMM_URL_PRV"]) ) { unset($comment["PROPS"]["UF_BLOG_COMM_URL_PRV"]); } } $comment["POST_TEXT"] = self::convertDiskFileBBCode( $comment["POST_TEXT"], 'BLOG_COMMENT', $comment["ID"], $comment["AUTHOR_ID"], $comment["ATTACHMENTS"] ); $comment["POST_TEXT_FORMATTED"] = preg_replace( [ '|\[DISK\sFILE\sID=[n]*\d+\]|', '|\[DOCUMENT\sID=[n]*\d+\]|' ], '', $comment["POST_TEXT"] ); $comment['POST_TEXT_FORMATTED'] = Mention::clear($comment['POST_TEXT_FORMATTED']); if ($p) { $p->arUserfields = []; } $images = []; $allow = [ 'IMAGE' => 'Y' ]; $parserParameters = []; $comment["POST_TEXT_FORMATTED"] = $p->convert($comment["POST_TEXT_FORMATTED"], false, $images, $allow, $parserParameters); } $comment["DATE_CREATE_FORMATTED"] = self::formatDateTimeToGMT($comment['DATE_CREATE'], $comment['AUTHOR_ID']); } /** * Returns mail-hash url * * @param string $url Entity Link. * @param int $userId User Id. * @param string $entityType Entity Type. * @param int $entityId Entity Id. * @param string $siteId Site id (2-char). * @return bool|string * @throws Main\LoaderException */ public static function getReplyToUrl($url, $userId, $entityType, $entityId, $siteId, $backUrl = null) { $result = false; $url = (string)$url; $userId = (int)$userId; $entityType = (string)$entityType; $entityId = (int)$entityId; $siteId = (string)$siteId; if ( $url === '' || $userId <= 0 || $entityType === '' || $entityId <= 0 || $siteId === '' || !Loader::includeModule('mail') ) { return $result; } $urlRes = \Bitrix\Mail\User::getReplyTo( $siteId, $userId, $entityType, $entityId, $url, $backUrl ); if (is_array($urlRes)) { [ , $backUrl ] = $urlRes; if ($backUrl) { $result = $backUrl; } } return $result; } /** * Returns data of attached files * * @param array $valueList Attachments List. * @param string|bool|false $siteId Site Id (2-chars). * @return array * @throws Main\LoaderException */ public static function getAttachmentsData($valueList, $siteId = false): array { $result = []; if (!Loader::includeModule('disk')) { return $result; } if ( !$siteId || (string)$siteId === '' ) { $siteId = SITE_ID; } foreach ($valueList as $value) { $attachedObject = AttachedObject::loadById($value, [ 'OBJECT' ]); if( !$attachedObject || !$attachedObject->getFile() ) { continue; } $attachedObjectUrl = \Bitrix\Disk\UrlManager::getUrlUfController('show', [ 'attachedId' => $value ]); $result[$value] = [ "ID" => $value, "OBJECT_ID" => $attachedObject->getFile()->getId(), "NAME" => $attachedObject->getFile()->getName(), "SIZE" => \CFile::formatSize($attachedObject->getFile()->getSize()), "URL" => $attachedObjectUrl, "IS_IMAGE" => TypeFile::isImage($attachedObject->getFile()) ]; } return $result; } /** * Processes disk objects list and generates external links (for inline images) if needed * * @param array $valueList * @param string $entityType Entity Type. * @param int $entityId Entity Id. * @param int $authorId User Id. * @param array $attachmentList Attachments List. * @return array * @throws Main\LoaderException */ public static function getAttachmentUrlList($valueList = [], $entityType = '', $entityId = 0, $authorId = 0, $attachmentList = []): array { $result = []; if ( empty($valueList) || empty($attachmentList) || (int)$authorId <= 0 || (int)$entityId <= 0 || !Loader::includeModule('disk') ) { return $result; } $userFieldManager = Driver::getInstance()->getUserFieldManager(); [ $connectorClass, $moduleId ] = $userFieldManager->getConnectorDataByEntityType($entityType); foreach($valueList as $value) { $attachedFileId = false; $attachedObject = false; [ $type, $realValue ] = FileUserType::detectType($value); if ($type === FileUserType::TYPE_NEW_OBJECT) { $attachedObject = AttachedObject::load([ '=ENTITY_TYPE' => $connectorClass, 'ENTITY_ID' => $entityId, '=MODULE_ID' => $moduleId, 'OBJECT_ID'=> $realValue ], [ 'OBJECT' ]); if($attachedObject) { $attachedFileId = $attachedObject->getId(); } } else { $attachedFileId = $realValue; } if ( (int)$attachedFileId > 0 && !empty($attachmentList[$attachedFileId]) ) { if (!$attachmentList[$attachedFileId]["IS_IMAGE"]) { $result[$value] = [ 'TYPE' => 'file', 'URL' => $attachmentList[$attachedFileId]["URL"] ]; } else { if (!$attachedObject) { $attachedObject = AttachedObject::loadById($attachedFileId, [ 'OBJECT' ]); } if ($attachedObject) { $file = $attachedObject->getFile(); $extLinks = $file->getExternalLinks([ 'filter' => [ 'OBJECT_ID' => $file->getId(), 'CREATED_BY' => $authorId, 'TYPE' => \Bitrix\Disk\Internals\ExternalLinkTable::TYPE_MANUAL, 'IS_EXPIRED' => false, ], 'limit' => 1, ]); if (empty($extLinks)) { $externalLink = $file->addExternalLink([ 'CREATED_BY' => $authorId, 'TYPE' => \Bitrix\Disk\Internals\ExternalLinkTable::TYPE_MANUAL, ]); } else { /** @var \Bitrix\Disk\ExternalLink $externalLink */ $externalLink = reset($extLinks); } if ($externalLink) { $originalFile = $file->getFile(); $result[$value] = [ 'TYPE' => 'image', 'URL' => Driver::getInstance()->getUrlManager()->getUrlExternalLink( [ 'hash' => $externalLink->getHash(), 'action' => 'showFile' ], true ), 'WIDTH' => (int)$originalFile["WIDTH"], 'HEIGHT' => (int)$originalFile["HEIGHT"] ]; } } } } } return $result; } /** * Converts formatted text replacing pseudo-BB code MAIL DISK, using calculated URLs * * @param string $text Text to convert. * @param array $attachmentList Attachments List. * @return mixed|string */ public static function convertMailDiskFileBBCode($text = '', $attachmentList = []) { if (preg_match_all('|\[MAIL\sDISK\sFILE\sID=([n]*\d+)\]|', $text, $matches)) { foreach($matches[1] as $inlineFileId) { $attachmentId = false; if (mb_strpos($inlineFileId, 'n') === 0) { $found = false; foreach($attachmentList as $attachmentId => $attachment) { if ( isset($attachment["OBJECT_ID"]) && (int)$attachment["OBJECT_ID"] === (int)mb_substr($inlineFileId, 1) ) { $found = true; break; } } if (!$found) { $attachmentId = false; } } else { $attachmentId = $inlineFileId; } if ((int)$attachmentId > 0) { $text = preg_replace( '|\[MAIL\sDISK\sFILE\sID='.$inlineFileId.'\]|', '[URL='.$attachmentList[$attachmentId]["URL"].']['.$attachmentList[$attachmentId]["NAME"].'][/URL]', $text ); } } $p = new \CTextParser(); $p->allow = [ 'HTML' => 'Y', 'ANCHOR' => 'Y' ]; $text = $p->convertText($text); } return $text; } /** * Converts DISK FILE BB-code to the pseudo-BB code MAIL DISK FILE or IMG BB-code * * @param string $text Text to convert. * @param string $entityType Entity Type. * @param int $entityId Entity Type. * @param int $authorId User id. * @param array $attachmentList Attachments List. * @return mixed */ public static function convertDiskFileBBCode($text, $entityType, $entityId, $authorId, $attachmentList = []) { $text = trim((string)$text); $authorId = (int)$authorId; $entityType = (string)$entityType; $entityId = (int)$entityId; if ( $text === '' || empty($attachmentList) || $authorId <= 0 || $entityType === '' || $entityId <= 0 ) { return $text; } if (preg_match_all('|\[DISK\sFILE\sID=([n]*\d+)\]|', $text, $matches)) { $attachmentUrlList = self::getAttachmentUrlList( $matches[1], $entityType, $entityId, $authorId, $attachmentList ); foreach($matches[1] as $inlineFileId) { if (!empty($attachmentUrlList[$inlineFileId])) { $needCreatePicture = false; $sizeSource = $sizeDestination = []; \CFile::scaleImage( $attachmentUrlList[$inlineFileId]['WIDTH'], $attachmentUrlList[$inlineFileId]['HEIGHT'], [ 'width' => 400, 'height' => 1000 ], BX_RESIZE_IMAGE_PROPORTIONAL, $needCreatePicture, $sizeSource, $sizeDestination ); $replacement = ( $attachmentUrlList[$inlineFileId]["TYPE"] === 'image' ? '[IMG WIDTH='.(int)$sizeDestination['width'].' HEIGHT='.(int)$sizeDestination['height'].']'.\htmlspecialcharsBack($attachmentUrlList[$inlineFileId]["URL"]).'[/IMG]' : '[MAIL DISK FILE ID='.$inlineFileId.']' ); $text = preg_replace( '|\[DISK\sFILE\sID='.$inlineFileId.'\]|', $replacement, $text ); } } } return $text; } /** * Calculates if text has inline disk file images * * @param string $text text with BB-codes * @param array $ufData uf of disk type. * @return boolean */ public static function hasTextInlineImage(string $text = '', array $ufData = []): bool { $result = false; if ( preg_match_all("#\\[disk file id=(n?\\d+)\\]#is".BX_UTF_PCRE_MODIFIER, $text, $matches) && Loader::includeModule('disk') ) { $userFieldManager = Driver::getInstance()->getUserFieldManager(); foreach ($matches[1] as $id) { $fileModel = null; [ $type, $realValue ] = FileUserType::detectType($id); if ($type === FileUserType::TYPE_NEW_OBJECT) { $fileModel = File::loadById($realValue); if(!$fileModel) { continue; } } else { $attachedModel = $userFieldManager->getAttachedObjectById($realValue); if(!$attachedModel) { continue; } $attachedModel->setOperableEntity([ 'ENTITY_ID' => $ufData['ENTITY_ID'], 'ENTITY_VALUE_ID' => $ufData['ENTITY_VALUE_ID'] ]); $fileModel = $attachedModel->getFile(); } if(TypeFile::isImage($fileModel)) { $result = true; break; } } } return $result; } /** * Formsts date time to the value of author + GMT offset * * @param string $dateTimeSource Date/Time in site format. * @param int $authorId User Id. * @return string */ public static function formatDateTimeToGMT($dateTimeSource, $authorId): string { if (empty($dateTimeSource)) { return ''; } $serverTs = \MakeTimeStamp($dateTimeSource) - \CTimeZone::getOffset(); $serverGMTOffset = (int)date('Z'); $authorOffset = (int)\CTimeZone::getOffset($authorId); $authorGMTOffset = $serverGMTOffset + $authorOffset; $authorGMTOffsetFormatted = 'GMT'; if ($authorGMTOffset !== 0) { $authorGMTOffsetFormatted .= ($authorGMTOffset >= 0 ? '+' : '-').sprintf('%02d', floor($authorGMTOffset / 3600)).':'.sprintf('%02u', ($authorGMTOffset % 3600) / 60); } return \FormatDate( preg_replace('/[\/.,\s:][s]/', '', \Bitrix\Main\Type\Date::convertFormatToPhp(FORMAT_DATETIME)), ($serverTs + $authorOffset) ).' ('.$authorGMTOffsetFormatted.')'; } /** * Returns (non-idea) blog group list * * @param array $params Parameters. * @return array */ public static function getSonetBlogGroupIdList($params): array { $result = []; if (!Loader::includeModule('blog')) { throw new Main\SystemException("Could not load 'blog' module."); } $cacheTtl = 3153600; $cacheId = 'blog_group_list_'.md5(serialize($params)); $cacheDir = '/blog/group/'; $cache = new \CPHPCache; if($cache->initCache($cacheTtl, $cacheId, $cacheDir)) { $result = $cache->getVars(); } else { $cache->startDataCache(); $ideaBlogGroupIdList = array(); if (ModuleManager::isModuleInstalled("idea")) { $res = \CSite::getList("sort", "desc", Array("ACTIVE" => "Y")); while ($site = $res->fetch()) { $val = Option::get("idea", "blog_group_id", false, $site["LID"]); if ($val) { $ideaBlogGroupIdList[] = $val; } } } $filter = array(); if (!empty($params["SITE_ID"])) { $filter['SITE_ID'] = $params["SITE_ID"]; } if (!empty($ideaBlogGroupIdList)) { $filter['!@ID'] = $ideaBlogGroupIdList; } $res = \CBlogGroup::getList(array(), $filter, false, false, array("ID")); while($blogGroup = $res->fetch()) { $result[] = $blogGroup["ID"]; } $cache->endDataCache($result); } return $result; } /** * Creates a user blog (when it is the first post of the user) * * @param array $params Parameters. * @return bool|array * @throws Main\ArgumentException * @throws Main\LoaderException * @throws Main\SystemException */ public static function createUserBlog($params) { $result = false; if (!Loader::includeModule('blog')) { throw new Main\SystemException("Could not load 'blog' module."); } if ( !isset($params["BLOG_GROUP_ID"], $params["USER_ID"], $params["SITE_ID"]) || (int)$params["BLOG_GROUP_ID"] <= 0 || (int)$params["USER_ID"] <= 0 || (string)$params["SITE_ID"] === '' ) { return false; } if ( !isset($params["PATH_TO_BLOG"]) || $params["PATH_TO_BLOG"] == '' ) { $params["PATH_TO_BLOG"] = ""; } $connection = Application::getConnection(); $helper = $connection->getSqlHelper(); $fields = array( "=DATE_UPDATE" => $helper->getCurrentDateTimeFunction(), "=DATE_CREATE" => $helper->getCurrentDateTimeFunction(), "GROUP_ID" => (int)$params["BLOG_GROUP_ID"], "ACTIVE" => "Y", "OWNER_ID" => (int)$params["USER_ID"], "ENABLE_COMMENTS" => "Y", "ENABLE_IMG_VERIF" => "Y", "EMAIL_NOTIFY" => "Y", "ENABLE_RSS" => "Y", "ALLOW_HTML" => "N", "ENABLE_TRACKBACK" => "N", "SEARCH_INDEX" => "Y", "USE_SOCNET" => "Y", "PERMS_POST" => Array( 1 => "I", 2 => "I" ), "PERMS_COMMENT" => Array( 1 => "P", 2 => "P" ) ); $res = \Bitrix\Main\UserTable::getList(array( 'order' => array(), 'filter' => array( "ID" => $params["USER_ID"] ), 'select' => array("NAME", "LAST_NAME", "LOGIN") )); if ($user = $res->fetch()) { $fields["NAME"] = Loc::getMessage("BLG_NAME")." ".( $user["NAME"]."".$user["LAST_NAME"] === '' ? $user["LOGIN"] : $user["NAME"]." ".$user["LAST_NAME"] ); $fields["URL"] = str_replace(" ", "_", $user["LOGIN"])."-blog-".$params["SITE_ID"]; $urlCheck = preg_replace("/[^a-zA-Z0-9_-]/i", "", $fields["URL"]); if ($urlCheck !== $fields["URL"]) { $fields["URL"] = "u".$params["USER_ID"]."-blog-".$params["SITE_ID"]; } if(\CBlog::getByUrl($fields["URL"])) { $uind = 0; do { $uind++; $fields["URL"] .= $uind; } while (\CBlog::getByUrl($fields["URL"])); } $fields["PATH"] = \CComponentEngine::makePathFromTemplate( $params["PATH_TO_BLOG"], array( "blog" => $fields["URL"], "user_id" => $fields["OWNER_ID"] ) ); if ($blogID = \CBlog::add($fields)) { BXClearCache(true, "/blog/form/blog/"); $rightsFound = false; $featureOperationPerms = \CSocNetFeaturesPerms::getOperationPerm( SONET_ENTITY_USER, $fields["OWNER_ID"], "blog", "view_post" ); if ($featureOperationPerms === SONET_RELATIONS_TYPE_ALL) { $rightsFound = true; } if ($rightsFound) { \CBlog::addSocnetRead($blogID); } $result = \CBlog::getByID($blogID); } } return $result; } /** * get urlPreview property value from text with links * * @param $text string * @param bool|true $html * @return bool|string * @throws Main\ArgumentTypeException */ public static function getUrlPreviewValue($text, $html = true) { static $parser = false; $value = false; if (empty($text)) { return $value; } if (!$parser) { $parser = new \CTextParser(); } if ($html) { $text = $parser->convertHtmlToBB($text); } preg_match_all("/\[url\s*=\s*([^\]]*)\](.+?)\[\/url\]/is".BX_UTF_PCRE_MODIFIER, $text, $res); if ( !empty($res) && !empty($res[1]) ) { $url = ( !Application::isUtfMode() ? \Bitrix\Main\Text\Encoding::convertEncoding($res[1][0], 'UTF-8', \Bitrix\Main\Context::getCurrent()->getCulture()->getCharset()) : $res[1][0] ); $metaData = UrlPreview::getMetadataAndHtmlByUrl($url, true, false); if ( !empty($metaData) && !empty($metaData["ID"]) && (int)$metaData["ID"] > 0 ) { $signer = new \Bitrix\Main\Security\Sign\Signer(); $value = $signer->sign($metaData["ID"].'', UrlPreview::SIGN_SALT); } } return $value; } /** * Returns rendered url preview block * * @param array $uf * @param array $params * @return string|boolean */ public static function getUrlPreviewContent($uf, $params = array()) { global $APPLICATION; $res = false; if ($uf["USER_TYPE"]["USER_TYPE_ID"] !== 'url_preview') { return $res; } ob_start(); $APPLICATION->includeComponent( "bitrix:system.field.view", $uf["USER_TYPE"]["USER_TYPE_ID"], array( "LAZYLOAD" => (isset($params["LAZYLOAD"]) && $params["LAZYLOAD"] === "Y" ? "Y" : "N"), "MOBILE" => (isset($params["MOBILE"]) && $params["MOBILE"] === "Y" ? "Y" : "N"), "arUserField" => $uf, "arAddField" => array( "NAME_TEMPLATE" => ($params["NAME_TEMPLATE"] ?? false), "PATH_TO_USER" => ($params["PATH_TO_USER"] ?? '') ) ), null, array("HIDE_ICONS"=>"Y") ); $res = ob_get_clean(); return $res; } public static function getExtranetUserIdList() { static $result = false; global $CACHE_MANAGER; if ($result === false) { $result = array(); if (!ModuleManager::isModuleInstalled('extranet')) { return $result; } $ttl = (defined("BX_COMP_MANAGED_CACHE") ? 2592000 : 600); $cacheId = 'sonet_ex_userid'; $cache = new \CPHPCache; $cacheDir = '/bitrix/sonet/user_ex'; if($cache->initCache($ttl, $cacheId, $cacheDir)) { $tmpVal = $cache->getVars(); $result = $tmpVal['EX_USER_ID']; unset($tmpVal); } else { if (defined("BX_COMP_MANAGED_CACHE")) { $CACHE_MANAGER->startTagCache($cacheDir); } $filter = array( 'UF_DEPARTMENT_SINGLE' => false ); $externalAuthIdList = self::checkPredefinedAuthIdList(array('bot', 'email', 'controller', 'sale', 'imconnector')); if (!empty($externalAuthIdList)) { $filter['!=EXTERNAL_AUTH_ID'] = $externalAuthIdList; } $res = \Bitrix\Main\UserTable::getList(array( 'order' => [], 'filter' => $filter, 'select' => array('ID') )); while($user = $res->fetch()) { $result[] = $user["ID"]; } $adminList = []; $res = \Bitrix\Main\UserGroupTable::getList(array( 'order' => [], 'filter' => [ '=GROUP_ID' => 1 ], 'select' => [ 'USER_ID' ] )); while($relationFields = $res->fetch()) { $adminList[] = $relationFields["USER_ID"]; } $result = array_diff($result, $adminList); if (defined("BX_COMP_MANAGED_CACHE")) { $CACHE_MANAGER->registerTag('sonet_user2group'); $CACHE_MANAGER->registerTag('sonet_extranet_user_list'); $CACHE_MANAGER->endTagCache(); } if($cache->startDataCache()) { $cache->endDataCache(array( 'EX_USER_ID' => $result )); } } } return $result; } public static function getEmailUserIdList() { global $CACHE_MANAGER; $result = array(); if ( !ModuleManager::isModuleInstalled('mail') || !ModuleManager::isModuleInstalled('intranet') ) { return $result; } $ttl = (defined("BX_COMP_MANAGED_CACHE") ? 2592000 : 600); $cacheId = 'sonet_email_userid'; $cache = new \CPHPCache; $cacheDir = '/bitrix/sonet/user_email'; if($cache->initCache($ttl, $cacheId, $cacheDir)) { $tmpVal = $cache->getVars(); $result = $tmpVal['EMAIL_USER_ID']; unset($tmpVal); } else { if (defined("BX_COMP_MANAGED_CACHE")) { $CACHE_MANAGER->startTagCache($cacheDir); } $res = \Bitrix\Main\UserTable::getList(array( 'order' => array(), 'filter' => array( '=EXTERNAL_AUTH_ID' => 'email' ), 'select' => array('ID') )); while($user = $res->fetch()) { $result[] = $user["ID"]; } if (defined("BX_COMP_MANAGED_CACHE")) { $CACHE_MANAGER->registerTag('USER_CARD'); $CACHE_MANAGER->endTagCache(); } if($cache->startDataCache()) { $cache->endDataCache(array( 'EMAIL_USER_ID' => $result )); } } return $result; } public static function getExtranetSonetGroupIdList() { $result = array(); $ttl = (defined("BX_COMP_MANAGED_CACHE") ? 2592000 : 600); $cacheId = 'sonet_ex_groupid'; $cache = new \CPHPCache; $cacheDir = '/bitrix/sonet/group_ex'; if($cache->initCache($ttl, $cacheId, $cacheDir)) { $tmpVal = $cache->getVars(); $result = $tmpVal['EX_GROUP_ID']; unset($tmpVal); } elseif (Loader::includeModule('extranet')) { global $CACHE_MANAGER; if (defined("BX_COMP_MANAGED_CACHE")) { $CACHE_MANAGER->startTagCache($cacheDir); } $res = WorkgroupTable::getList(array( 'order' => array(), 'filter' => array( "=WorkgroupSite:GROUP.SITE_ID" => \CExtranet::getExtranetSiteID() ), 'select' => array('ID') )); while($sonetGroup = $res->fetch()) { $result[] = $sonetGroup["ID"]; if (defined("BX_COMP_MANAGED_CACHE")) { $CACHE_MANAGER->registerTag('sonet_group_'.$sonetGroup["ID"]); } } if (defined("BX_COMP_MANAGED_CACHE")) { $CACHE_MANAGER->registerTag('sonet_group'); $CACHE_MANAGER->endTagCache(); } if($cache->startDataCache()) { $cache->endDataCache(array( 'EX_GROUP_ID' => $result )); } } return $result; } public static function hasCommentSource($params): bool { $res = false; if (empty($params["LOG_EVENT_ID"])) { return $res; } $commentEvent = \CSocNetLogTools::findLogCommentEventByLogEventID($params["LOG_EVENT_ID"]); if ( isset($commentEvent["DELETE_CALLBACK"]) && $commentEvent["DELETE_CALLBACK"] !== "NO_SOURCE" ) { if ( $commentEvent["EVENT_ID"] === "crm_activity_add_comment" && isset($params["LOG_ENTITY_ID"]) && (int)$params["LOG_ENTITY_ID"] > 0 && Loader::includeModule('crm') ) { $result = \CCrmActivity::getList( array(), array( 'ID' => (int)$params["LOG_ENTITY_ID"], 'CHECK_PERMISSIONS' => 'N' ) ); if ($activity = $result->fetch()) { $res = ((int)$activity['TYPE_ID'] === \CCrmActivityType::Task); } } else { $res = true; } } return $res; } // only by current userid public static function processBlogPostShare($fields, $params) { $postId = (int)$fields["POST_ID"]; $blogId = (int)$fields["BLOG_ID"]; $siteId = $fields["SITE_ID"]; $sonetRights = $fields["SONET_RIGHTS"]; $newRights = $fields["NEW_RIGHTS"]; $userId = (int)$fields["USER_ID"]; $clearCommentsCache = (!isset($params['CLEAR_COMMENTS_CACHE']) || $params['CLEAR_COMMENTS_CACHE'] !== 'N'); $commentId = false; $logId = false; if ( Loader::includeModule('blog') && \CBlogPost::update($postId, array("SOCNET_RIGHTS" => $sonetRights, "HAS_SOCNET_ALL" => "N")) ) { BXClearCache(true, self::getBlogPostCacheDir(array( 'TYPE' => 'post', 'POST_ID' => $postId ))); BXClearCache(true, self::getBlogPostCacheDir(array( 'TYPE' => 'post_general', 'POST_ID' => $postId ))); BXClearCache(True, self::getBlogPostCacheDir(array( 'TYPE' => 'posts_popular', 'SITE_ID' => $siteId ))); $logSiteListNew = array(); $user2NotifyList = array(); $sonetPermissionList = \CBlogPost::getSocnetPermsName($postId); $extranet = Loader::includeModule("extranet"); $extranetSite = ($extranet ? \CExtranet::getExtranetSiteID() : false); $tzOffset = \CTimeZone::getOffset(); $res = \CBlogPost::getList( array(), array("ID" => $postId), false, false, array("ID", "BLOG_ID", "PUBLISH_STATUS", "TITLE", "AUTHOR_ID", "ENABLE_COMMENTS", "NUM_COMMENTS", "VIEWS", "CODE", "MICRO", "DETAIL_TEXT", "DATE_PUBLISH", "CATEGORY_ID", "HAS_SOCNET_ALL", "HAS_TAGS", "HAS_IMAGES", "HAS_PROPS", "HAS_COMMENT_IMAGES") ); $post = $res->fetch(); if (!$post) { return false; } if (!empty($post['DETAIL_TEXT'])) { $post['DETAIL_TEXT'] = \Bitrix\Main\Text\Emoji::decode($post['DETAIL_TEXT']); } $intranetUserIdList = ($extranet ? \CExtranet::getIntranetUsers() : false); $auxLiveParamList = array(); $sharedToIntranetUser = false; foreach ($sonetPermissionList as $type => $v) { foreach ($v as $vv) { if ( $type === "SG" && in_array($type . $vv["ENTITY_ID"], $newRights, true) ) { $renderParts = new Livefeed\RenderParts\SonetGroup(); $renderData = $renderParts->getData($vv["ENTITY_ID"]); if($sonetGroup = \CSocNetGroup::getByID($vv["ENTITY_ID"])) { $res = \CSocNetGroup::getSite($vv["ENTITY_ID"]); while ($groupSiteList = $res->fetch()) { $logSiteListNew[] = $groupSiteList["LID"]; } $auxLiveParamList[] = array( "ENTITY_TYPE" => 'SG', "ENTITY_ID" => $renderData['id'], "NAME" => $renderData['name'], "LINK" => $renderData['link'], "VISIBILITY" => ($sonetGroup["VISIBLE"] === "Y" ? "all" : "group_members") ); } } elseif ($type === "U") { if ( in_array("US" . $vv["ENTITY_ID"], $vv["ENTITY"], true) && in_array("UA", $newRights, true) ) { $renderParts = new Livefeed\RenderParts\User(); $renderData = $renderParts->getData(0); $auxLiveParamList[] = array( "ENTITY_TYPE" => 'UA', "ENTITY_ID" => 'UA', "NAME" => $renderData['name'], "LINK" => $renderData['link'], "VISIBILITY" => 'all' ); } elseif (in_array($type . $vv["ENTITY_ID"], $newRights, true)) { $renderParts = new Livefeed\RenderParts\User(); $renderData = $renderParts->getData($vv["ENTITY_ID"]); $user2NotifyList[] = $vv["ENTITY_ID"]; if ( $extranet && is_array($intranetUserIdList) && !in_array($vv["ENTITY_ID"], $intranetUserIdList) ) { $logSiteListNew[] = $extranetSite; $visibility = 'extranet'; } else { $sharedToIntranetUser = true; $visibility = 'intranet'; } $auxLiveParamList[] = array( "ENTITY_TYPE" => 'U', "ENTITY_ID" => $renderData['id'], "NAME" => $renderData['name'], "LINK" => $renderData['link'], "VISIBILITY" => $visibility ); } } elseif ( $type === "DR" && in_array($type.$vv["ENTITY_ID"], $newRights) ) { $renderParts = new Livefeed\RenderParts\Department(); $renderData = $renderParts->getData($vv["ENTITY_ID"]); $auxLiveParamList[] = array( "ENTITY_TYPE" => 'DR', "ENTITY_ID" => $renderData['id'], "NAME" => $renderData['name'], "LINK" => $renderData['link'], "VISIBILITY" => 'intranet' ); } } } $userIP = \CBlogUser::getUserIP(); $auxText = CommentAux\Share::getPostText(); $mention = ( isset($params["MENTION"]) && $params["MENTION"] === "Y" ); $commentFields = Array( "POST_ID" => $postId, "BLOG_ID" => $blogId, "POST_TEXT" => $auxText, "DATE_CREATE" => convertTimeStamp(time() + $tzOffset, "FULL"), "AUTHOR_IP" => $userIP[0], "AUTHOR_IP1" => $userIP[1], "PARENT_ID" => false, "AUTHOR_ID" => $userId, "SHARE_DEST" => implode(",", $newRights).($mention ? '|mention' : ''), ); $userIdSent = []; if($commentId = \CBlogComment::add($commentFields, false)) { if ($clearCommentsCache) { BXClearCache(true, self::getBlogPostCacheDir(array( 'TYPE' => 'post_comments', 'POST_ID' => $postId ))); } if ((int)$post["AUTHOR_ID"] !== $userId) { $fieldsIM = array( "TYPE" => "SHARE", "TITLE" => htmlspecialcharsback($post["TITLE"]), "URL" => \CComponentEngine::makePathFromTemplate( htmlspecialcharsBack($params["PATH_TO_POST"]), array( "post_id" => $postId, "user_id" => $post["AUTHOR_ID"] ) ), "ID" => $postId, "FROM_USER_ID" => $userId, "TO_USER_ID" => array($post["AUTHOR_ID"]), ); \CBlogPost::notifyIm($fieldsIM); $userIdSent[] = array_merge($userIdSent, $fieldsIM["TO_USER_ID"]); } if(!empty($user2NotifyList)) { $fieldsIM = array( "TYPE" => "SHARE2USERS", "TITLE" => htmlspecialcharsback($post["TITLE"]), "URL" => \CComponentEngine::makePathFromTemplate( htmlspecialcharsBack($params["PATH_TO_POST"]), array( "post_id" => $postId, "user_id" => $post["AUTHOR_ID"] )), "ID" => $postId, "FROM_USER_ID" => $userId, "TO_USER_ID" => $user2NotifyList, ); \CBlogPost::notifyIm($fieldsIM); $userIdSent[] = array_merge($userIdSent, $fieldsIM["TO_USER_ID"]); \CBlogPost::notifyMail(array( "type" => "POST_SHARE", "siteId" => $siteId, "userId" => $user2NotifyList, "authorId" => $userId, "postId" => $post["ID"], "postUrl" => \CComponentEngine::makePathFromTemplate( '/pub/post.php?post_id=#post_id#', array( "post_id"=> $post["ID"] ) ) )); } } $blogPostLivefeedProvider = new \Bitrix\Socialnetwork\Livefeed\BlogPost; /* update socnet log rights*/ $res = \CSocNetLog::getList( array("ID" => "DESC"), array( "EVENT_ID" => $blogPostLivefeedProvider->getEventId(), "SOURCE_ID" => $postId ), false, false, array("ID", "ENTITY_TYPE", "ENTITY_ID", "USER_ID", "EVENT_ID") ); if ($logEntry = $res->fetch()) { $logId = $logEntry["ID"]; $logSiteList = array(); $res = \CSocNetLog::getSite($logId); while ($logSite = $res->fetch()) { $logSiteList[] = $logSite["LID"]; } $logSiteListNew = array_unique(array_merge($logSiteListNew, $logSiteList)); if ( $extranet && $sharedToIntranetUser && count($logSiteListNew) == 1 && $logSiteListNew[0] == $extranetSite ) { $logSiteListNew[] = \CSite::getDefSite(); } $socnetPerms = self::getBlogPostSocNetPerms(array( 'postId' => $postId, 'authorId' => $post["AUTHOR_ID"] )); \CSocNetLogRights::deleteByLogID($logId); \CSocNetLogRights::add($logId, $socnetPerms, true, false); foreach($newRights as $GROUP_CODE) { if (preg_match('/^U(\d+)$/', $GROUP_CODE, $matches)) { ComponentHelper::userLogSubscribe(array( 'logId' => $logId, 'userId' => $matches[1], 'siteId' => $siteId, 'typeList' => array( 'FOLLOW', 'COUNTER_COMMENT_PUSH' ), 'followDate' => 'CURRENT' )); } } if (count(array_diff($logSiteListNew, $logSiteList)) > 0) { \CSocNetLog::update($logId, array( "ENTITY_TYPE" => $logEntry["ENTITY_TYPE"], // to use any real field "SITE_ID" => $logSiteListNew )); } if ($commentId > 0) { $connection = \Bitrix\Main\Application::getConnection(); $helper = $connection->getSqlHelper(); $logCommentFields = array( 'ENTITY_TYPE' => SONET_ENTITY_USER, 'ENTITY_ID' => $post["AUTHOR_ID"], 'EVENT_ID' => 'blog_comment', '=LOG_DATE' => $helper->getCurrentDateTimeFunction(), 'LOG_ID' => $logId, 'USER_ID' => $userId, 'MESSAGE' => $auxText, "TEXT_MESSAGE" => $auxText, 'MODULE_ID' => false, 'SOURCE_ID' => $commentId, 'RATING_TYPE_ID' => 'BLOG_COMMENT', 'RATING_ENTITY_ID' => $commentId ); \CSocNetLogComments::add($logCommentFields, false, false); } \CSocNetLogFollow::deleteByLogID($logId, "Y", true); /* subscribe share author */ self::userLogSubscribe([ 'logId' => $logId, 'userId' => $userId, 'typeList' => [ 'FOLLOW', 'COUNTER_COMMENT_PUSH', ], 'followDate' => 'CURRENT', ]); } /* update socnet groupd activity*/ foreach($newRights as $v) { if(mb_substr($v, 0, 2) === "SG") { $groupId = (int)mb_substr($v, 2); if($groupId > 0) { \CSocNetGroup::setLastActivity($groupId); } } } \Bitrix\Blog\Broadcast::send(array( "EMAIL_FROM" => \COption::getOptionString("main","email_from", "nobody@nobody.com"), "SOCNET_RIGHTS" => $newRights, "ENTITY_TYPE" => "POST", "ENTITY_ID" => $post["ID"], "AUTHOR_ID" => $post["AUTHOR_ID"], "URL" => \CComponentEngine::makePathFromTemplate( htmlspecialcharsBack($params["PATH_TO_POST"]), array( "post_id" => $post["ID"], "user_id" => $post["AUTHOR_ID"] ) ), "EXCLUDE_USERS" => $userIdSent )); if (!$mention) { \Bitrix\Main\FinderDestTable::merge(array( "CONTEXT" => "blog_post", "CODE" => \Bitrix\Main\FinderDestTable::convertRights($newRights) )); } if (\Bitrix\Main\Loader::includeModule('crm')) { \CCrmLiveFeedComponent::processCrmBlogPostRights($logId, $logEntry, $post, 'share'); } if ( (int)$commentId > 0 && ( !isset($params["LIVE"]) || $params["LIVE"] !== "N" ) ) { $provider = \Bitrix\Socialnetwork\CommentAux\Base::init(\Bitrix\Socialnetwork\CommentAux\Share::getType(), array( 'liveParamList' => $auxLiveParamList )); \CBlogComment::addLiveComment($commentId, array( "PATH_TO_USER" => $params["PATH_TO_USER"], "PATH_TO_POST" => \CComponentEngine::makePathFromTemplate( htmlspecialcharsBack($params["PATH_TO_POST"]), array( "post_id" => $post["ID"], "user_id" => $post["AUTHOR_ID"] ) ), "LOG_ID" => ($logId ? (int)$logId : 0), "AUX" => 'share', "AUX_LIVE_PARAMS" => $provider->getLiveParams(), "CAN_USER_COMMENT" => (!empty($params["CAN_USER_COMMENT"]) && $params["CAN_USER_COMMENT"] === 'Y' ? 'Y' : 'N') )); } } return $commentId; } public static function getUrlContext(): array { $result = []; if ( isset($_GET["entityType"]) && $_GET["entityType"] <> '' ) { $result["ENTITY_TYPE"] = $_GET["entityType"]; } if ( isset($_GET["entityId"]) && (int)$_GET["entityId"] > 0 ) { $result["ENTITY_ID"] = (int)$_GET["entityId"]; } return $result; } public static function addContextToUrl($url, $context) { $result = $url; if ( !empty($context) && !empty($context["ENTITY_TYPE"]) && !empty($context["ENTITY_ID"]) ) { $result = $url.(mb_strpos($url, '?') === false ? '?' : '&').'entityType='.$context["ENTITY_TYPE"].'&entityId='.$context["ENTITY_ID"]; } return $result; } public static function checkPredefinedAuthIdList($authIdList = array()) { if (!is_array($authIdList)) { $authIdList = array($authIdList); } foreach($authIdList as $key => $authId) { if ( $authId === 'replica' && !ModuleManager::isModuleInstalled("replica") ) { unset($authIdList[$key]); } if ( $authId === 'imconnector' && !ModuleManager::isModuleInstalled("imconnector") ) { unset($authIdList[$key]); } if ( $authId === 'bot' && !ModuleManager::isModuleInstalled("im") ) { unset($authIdList[$key]); } if ( $authId === 'email' && !ModuleManager::isModuleInstalled("mail") ) { unset($authIdList[$key]); } if ( in_array($authId, [ 'sale', 'shop' ]) && !ModuleManager::isModuleInstalled("sale") ) { unset($authIdList[$key]); } } return $authIdList; } public static function setModuleUsed(): void { $optionValue = Option::get('socialnetwork', 'is_used', false); if (!$optionValue) { Option::set('socialnetwork', 'is_used', true); } } public static function getModuleUsed(): bool { return (bool)Option::get('socialnetwork', 'is_used', false); } public static function setComponentOption($list, $params = array()): bool { if (!is_array($list)) { return false; } $siteId = (!empty($params["SITE_ID"]) ? $params["SITE_ID"] : SITE_ID); $sefFolder = (!empty($params["SEF_FOLDER"]) ? $params["SEF_FOLDER"] : false); foreach ($list as $value) { if ( empty($value["OPTION"]) || empty($value["OPTION"]["MODULE_ID"]) || empty($value["OPTION"]["NAME"]) || empty($value["VALUE"]) ) { continue; } $optionValue = Option::get($value["OPTION"]["MODULE_ID"], $value["OPTION"]["NAME"], false, $siteId); if ( !$optionValue || ( !!($value["CHECK_SEF_FOLDER"] ?? false) && $sefFolder && mb_substr($optionValue, 0, mb_strlen($sefFolder)) !== $sefFolder ) ) { Option::set($value["OPTION"]["MODULE_ID"], $value["OPTION"]["NAME"], $value["VALUE"], $siteId); } } return true; } public static function getSonetGroupAvailable($params = array(), &$limitReached = false) { global $USER; $currentUserId = $USER->getId(); $limit = (isset($params['limit']) && (int)$params['limit'] > 0 ? (int)$params['limit'] : 500); $useProjects = (!empty($params['useProjects']) && $params['useProjects'] === 'Y' ? 'Y' : 'N'); $siteId = (!empty($params['siteId']) ? $params['siteId'] : SITE_ID); $landing = (!empty($params['landing']) && $params['landing'] === 'Y' ? 'Y' : ''); $currentCache = \Bitrix\Main\Data\Cache::createInstance(); $cacheTtl = defined("BX_COMP_MANAGED_CACHE") ? 3153600 : 3600*4; $cacheId = 'dest_group_'.$siteId.'_'.$currentUserId.'_'.$limit.$useProjects.$landing; $cacheDir = '/sonet/dest_sonet_groups/'.$siteId.'/'.$currentUserId; if($currentCache->startDataCache($cacheTtl, $cacheId, $cacheDir)) { global $CACHE_MANAGER; $limitReached = false; $filter = [ 'features' => array("blog", array("premoderate_post", "moderate_post", "write_post", "full_post")), 'limit' => $limit, 'useProjects' => $useProjects, 'site_id' => $siteId, ]; if ($landing === 'Y') { $filter['landing'] = 'Y'; } $groupList = \CSocNetLogDestination::getSocnetGroup($filter, $limitReached); if(defined("BX_COMP_MANAGED_CACHE")) { $CACHE_MANAGER->startTagCache($cacheDir); foreach($groupList as $group) { $CACHE_MANAGER->registerTag("sonet_features_G_".$group["entityId"]); $CACHE_MANAGER->registerTag("sonet_group_".$group["entityId"]); } $CACHE_MANAGER->registerTag("sonet_user2group_U".$currentUserId); if ($landing === 'Y') { $CACHE_MANAGER->registerTag("sonet_group"); } $CACHE_MANAGER->endTagCache(); } $currentCache->endDataCache(array( 'groups' => $groupList, 'limitReached' => $limitReached )); } else { $tmp = $currentCache->getVars(); $groupList = $tmp['groups']; $limitReached = $tmp['limitReached']; } if ( !$limitReached && \CSocNetUser::isCurrentUserModuleAdmin() ) { $limitReached = true; } return $groupList; } public static function canAddComment($logEntry = array(), $commentEvent = array()) { $canAddComments = false; global $USER; if ( !is_array($logEntry) && (int)$logEntry > 0 ) { $res = \CSocNetLog::getList( array(), array( "ID" => (int)$logEntry ), false, false, array("ID", "ENTITY_TYPE", "ENTITY_ID", "EVENT_ID", "USER_ID") ); if (!($logEntry = $res->fetch())) { return $canAddComments; } } if ( !is_array($logEntry) || empty($logEntry) || empty($logEntry["EVENT_ID"]) ) { return $canAddComments; } if ( !is_array($commentEvent) || empty($commentEvent) ) { $commentEvent = \CSocNetLogTools::findLogCommentEventByLogEventID($logEntry["EVENT_ID"]); } if (is_array($commentEvent)) { $feature = \CSocNetLogTools::findFeatureByEventID($commentEvent["EVENT_ID"]); if ( array_key_exists("OPERATION_ADD", $commentEvent) && $commentEvent["OPERATION_ADD"] === "log_rights" ) { $canAddComments = \CSocNetLogRights::checkForUser($logEntry["ID"], $USER->getID()); } elseif ( $feature && array_key_exists("OPERATION_ADD", $commentEvent) && $commentEvent["OPERATION_ADD"] <> '' ) { $canAddComments = \CSocNetFeaturesPerms::canPerformOperation( $USER->getID(), $logEntry["ENTITY_TYPE"], $logEntry["ENTITY_ID"], ($feature === "microblog" ? "blog" : $feature), $commentEvent["OPERATION_ADD"], \CSocNetUser::isCurrentUserModuleAdmin() ); } else { $canAddComments = true; } } return $canAddComments; } public static function addLiveComment($comment = [], $logEntry = [], $commentEvent = [], $params = []): array { global $USER_FIELD_MANAGER; $result = []; if ( !is_array($comment) || empty($comment) || !is_array($logEntry) || empty($logEntry) || !is_array($commentEvent) || empty($commentEvent) ) { return $result; } $aux = !empty($params['AUX']); if ( !isset($params["ACTION"]) || !in_array($params["ACTION"], array("ADD", "UPDATE")) ) { $params["ACTION"] = "ADD"; } if ( !isset($params["LANGUAGE_ID"]) || empty($params["LANGUAGE_ID"]) ) { $params["LANGUAGE_ID"] = LANGUAGE_ID; } if ( !isset($params["SITE_ID"]) || empty($params["SITE_ID"]) ) { $params["SITE_ID"] = SITE_ID; } if ($params["ACTION"] === "ADD") { if ( !empty($commentEvent) && !empty($commentEvent["METHOD_CANEDIT"]) && !empty($comment["SOURCE_ID"]) && (int)$comment["SOURCE_ID"] > 0 && !empty($logEntry["SOURCE_ID"]) && (int)$logEntry["SOURCE_ID"] > 0 ) { $canEdit = call_user_func($commentEvent["METHOD_CANEDIT"], array( "LOG_SOURCE_ID" => $logEntry["SOURCE_ID"], "COMMENT_SOURCE_ID" => $comment["SOURCE_ID"], "USER_ID" => $comment["USER_ID"] )); } else { $canEdit = !$aux; } } $result["hasEditCallback"] = ( $canEdit && is_array($commentEvent) && isset($commentEvent["UPDATE_CALLBACK"]) && ( $commentEvent["UPDATE_CALLBACK"] === "NO_SOURCE" || is_callable($commentEvent["UPDATE_CALLBACK"]) ) ? "Y" : "N" ); $result["hasDeleteCallback"] = ( $canEdit && is_array($commentEvent) && isset($commentEvent["DELETE_CALLBACK"]) && ( $commentEvent["DELETE_CALLBACK"] === "NO_SOURCE" || is_callable($commentEvent["DELETE_CALLBACK"]) ) ? "Y" : "N" ); if ( !isset($params["SOURCE_ID"]) || (int)$params["SOURCE_ID"] <= 0 ) { foreach (EventManager::getInstance()->findEventHandlers('socialnetwork', 'OnAfterSonetLogEntryAddComment') as $handler) // send notification { ExecuteModuleEventEx($handler, array($comment)); } } $result["arComment"] = $comment; foreach($result["arComment"] as $key => $value) { if (mb_strpos($key, "~") === 0) { unset($result["arComment"][$key]); } } $result["arComment"]["RATING_USER_HAS_VOTED"] = "N"; $result["sourceID"] = $comment["SOURCE_ID"]; $result["timestamp"] = makeTimeStamp( array_key_exists("LOG_DATE_FORMAT", $comment) ? $comment["LOG_DATE_FORMAT"] : $comment["LOG_DATE"] ); $comment["UF"] = $USER_FIELD_MANAGER->getUserFields("SONET_COMMENT", $comment["ID"], LANGUAGE_ID); if ( array_key_exists("UF_SONET_COM_DOC", $comment["UF"]) && array_key_exists("VALUE", $comment["UF"]["UF_SONET_COM_DOC"]) && is_array($comment["UF"]["UF_SONET_COM_DOC"]["VALUE"]) && count($comment["UF"]["UF_SONET_COM_DOC"]["VALUE"]) > 0 && $commentEvent["EVENT_ID"] !== "tasks_comment" ) { $logEntryRights = array(); $res = \CSocNetLogRights::getList(array(), array("LOG_ID" => $logEntry["ID"])); while ($right = $res->fetch()) { $logEntryRights[] = $right["GROUP_CODE"]; } \CSocNetLogTools::setUFRights($comment["UF"]["UF_SONET_COM_DOC"]["VALUE"], $logEntryRights); } $result['timeFormatted'] = formatDateFromDB( ($comment['LOG_DATE_FORMAT'] ?? $comment['LOG_DATE']), self::getTimeFormat($params['TIME_FORMAT']) ); $authorFields = self::getAuthorData([ 'userId' => $comment['USER_ID'], ]); $createdBy = self::getCreatedByData([ 'userFields' => $authorFields, 'languageId' => $params['LANGUAGE_ID'], 'nameTemplate' => $params['NAME_TEMPLATE'], 'showLogin' => $params['SHOW_LOGIN'], 'pathToUser' => $params['PATH_TO_USER'], ]); $commentFormatted = array( 'LOG_DATE' => $comment["LOG_DATE"], "LOG_DATE_FORMAT" => $comment["LOG_DATE_FORMAT"] ?? null, "LOG_DATE_DAY" => ConvertTimeStamp(MakeTimeStamp($comment['LOG_DATE']), 'SHORT'), 'LOG_TIME_FORMAT' => $result['timeFormatted'], "MESSAGE" => $comment["MESSAGE"], "MESSAGE_FORMAT" => $comment["~MESSAGE"] ?? null, 'CREATED_BY' => $createdBy, "AVATAR_SRC" => \CSocNetLogTools::formatEvent_CreateAvatar($authorFields, $params, ""), 'USER_ID' => $comment['USER_ID'], ); if ( array_key_exists("CLASS_FORMAT", $commentEvent) && array_key_exists("METHOD_FORMAT", $commentEvent) ) { $fieldsFormatted = call_user_func( array($commentEvent["CLASS_FORMAT"], $commentEvent["METHOD_FORMAT"]), $comment, $params ); $commentFormatted["MESSAGE_FORMAT"] = htmlspecialcharsback($fieldsFormatted["EVENT_FORMATTED"]["MESSAGE"]); } else { $commentFormatted["MESSAGE_FORMAT"] = $comment["MESSAGE"]; } if ( array_key_exists("CLASS_FORMAT", $commentEvent) && array_key_exists("METHOD_FORMAT", $commentEvent) ) { $fieldsFormatted = call_user_func( array($commentEvent["CLASS_FORMAT"], $commentEvent["METHOD_FORMAT"]), $comment, array_merge( $params, array( "MOBILE" => "Y" ) ) ); $messageMobile = htmlspecialcharsback($fieldsFormatted["EVENT_FORMATTED"]["MESSAGE"]); } else { $messageMobile = $comment["MESSAGE"]; } $result["arCommentFormatted"] = $commentFormatted; if ( isset($params["PULL"]) && $params["PULL"] === "Y" ) { $liveFeedCommentsParams = self::getLFCommentsParams([ 'ID' => $logEntry['ID'], 'EVENT_ID' => $logEntry['EVENT_ID'], 'ENTITY_TYPE' => $logEntry['ENTITY_TYPE'], 'ENTITY_ID' => $logEntry['ENTITY_ID'], 'SOURCE_ID' => $logEntry['SOURCE_ID'], 'PARAMS' => $logEntry['PARAMS'] ?? null ]); $entityXMLId = $liveFeedCommentsParams['ENTITY_XML_ID']; $listCommentId = ( !!$comment["SOURCE_ID"] ? $comment["SOURCE_ID"] : $comment["ID"] ); $eventHandlerID = EventManager::getInstance()->addEventHandlerCompatible("main", "system.field.view.file", array("CSocNetLogTools", "logUFfileShow")); $rights = \CSocNetLogComponent::getCommentRights([ 'EVENT_ID' => $logEntry['EVENT_ID'], 'SOURCE_ID' => $logEntry['SOURCE_ID'], 'USER_ID' => $comment['USER_ID'] ]); $postContentTypeId = ''; $commentContentTypeId = ''; $postContentId = \Bitrix\Socialnetwork\Livefeed\Provider::getContentId($logEntry); $canGetCommentContent = false; if ( !empty($postContentId['ENTITY_TYPE']) && ($postProvider = \Bitrix\Socialnetwork\Livefeed\Provider::getProvider($postContentId['ENTITY_TYPE'])) && ($commentProvider = $postProvider->getCommentProvider()) ) { $postContentTypeId = $postProvider->getContentTypeId(); $commentProviderClassName = get_class($commentProvider); $reflectionClass = new \ReflectionClass($commentProviderClassName); $canGetCommentContent = ($reflectionClass->getMethod('initSourceFields')->class == $commentProviderClassName); if ($canGetCommentContent) { $commentContentTypeId = $commentProvider->getContentTypeId(); } } $records = static::getLiveCommentRecords([ 'commentId' => $listCommentId, 'ratingTypeId' => $comment['RATING_TYPE_ID'], 'timestamp' => $result['timestamp'], 'author' => [ 'ID' => $authorFields['ID'], 'NAME' => $authorFields['NAME'], 'LAST_NAME' => $authorFields['LAST_NAME'], 'SECOND_NAME' => $authorFields['SECOND_NAME'], 'PERSONAL_GENDER' => $authorFields['PERSONAL_GENDER'], 'AVATAR' => $commentFormatted['AVATAR_SRC'], ], 'uf' => $comment['UF'], 'ufFormatted' => $commentFormatted['UF'] ?? null, 'postMessageTextOriginal' => $comment['~MESSAGE'] ?? null, 'postMessageTextFormatted' => $commentFormatted['MESSAGE_FORMAT'], 'mobileMessage' => $messageMobile, 'aux' => ($params['AUX'] ?? ''), 'auxLiveParams' => ($params['AUX_LIVE_PARAMS'] ?? []), ]); $viewUrl = (string)($comment['EVENT']['URL'] ?? ''); if (empty($viewUrl)) { $pathToLogEntry = (string)($params['PATH_TO_LOG_ENTRY'] ?? ''); if (!empty($pathToLogEntry)) { $viewUrl = \CComponentEngine::makePathFromTemplate( $pathToLogEntry, [ 'log_id' => $logEntry['ID'] ] ) . (mb_strpos($pathToLogEntry, '?') === false ? '?' : '&') . 'commentId=#ID#'; } } $rights['COMMENT_RIGHTS_CREATETASK'] = ( $canGetCommentContent && ModuleManager::isModuleInstalled('tasks') ? 'Y' : 'N' ); $res = static::sendLiveComment([ 'ratingTypeId' => $comment['RATING_TYPE_ID'], 'entityXMLId' => $entityXMLId, 'postContentTypeId' => $postContentTypeId, 'commentContentTypeId' => $commentContentTypeId, 'records' => $records, 'rights' => $rights, 'commentId' => $listCommentId, 'action' => ($params['ACTION'] === 'UPDATE' ? 'EDIT' : 'REPLY'), 'urlList' => [ 'view' => $viewUrl, 'edit' => "__logEditComment('" . $entityXMLId . "', '#ID#', '" . $logEntry["ID"] . "');", 'delete' => '/bitrix/components/bitrix/socialnetwork.log.entry/ajax.php?lang=' . $params['LANGUAGE_ID'] . '&action=delete_comment&delete_comment_id=#ID#&post_id=' . $logEntry['ID'] . '&site=' . $params['SITE_ID'], ], 'avatarSize' => $params['AVATAR_SIZE_COMMENT'] ?? null, 'nameTemplate' => $params['NAME_TEMPLATE'], 'dateTimeFormat' => $params['DATE_TIME_FORMAT'] ?? null, ]); if ($eventHandlerID > 0) { EventManager::getInstance()->removeEventHandler('main', 'system.field.view.file', $eventHandlerID); } $result['return_data'] = $res['JSON']; } return $result; } public static function addLiveSourceComment(array $params = []): void { global $USER_FIELD_MANAGER, $APPLICATION, $USER; $siteId = (string)($params['siteId'] ?? SITE_ID); $languageId = (string)($params['siteId'] ?? LANGUAGE_ID); $entityXmlId = (string)($params['entityXmlId'] ?? ''); $nameTemplate = (string)($params['nameTemplate'] ?? ''); $showLogin = (string)($params['showLogin'] ?? 'N'); $pathToUser = (string)($params['pathToUser'] ?? ''); $avatarSize = (int)($params['avatarSize'] ?? 100); $postProvider = $params['postProvider']; $commentProvider = $params['commentProvider']; if ( !$postProvider || !$commentProvider ) { return; } $commentId = $commentProvider->getEntityId(); $ratingTypeId = $commentProvider->getRatingTypeId(); $commentDateTime = $commentProvider->getSourceDateTime(); $commentAuthorId = $commentProvider->getSourceAuthorId(); $commentText = $commentProvider->getSourceDescription(); $userTypeEntityId = $commentProvider->getUserTypeEntityId(); $commentContentTypeId = $commentProvider->getContentTypeId(); $postContentTypeId = $postProvider->getContentTypeId(); $timestamp = ($commentDateTime ? makeTimeStamp($commentDateTime) : 0); if (!empty($userTypeEntityId)) { $comment['UF'] = $USER_FIELD_MANAGER->getUserFields($userTypeEntityId, $commentId, $languageId); } $timeFormatted = formatDateFromDB($commentDateTime, self::getTimeFormat()); $authorFields = self::getAuthorData([ 'userId' => $commentAuthorId, ]); $createdBy = self::getCreatedByData([ 'userFields' => $authorFields, 'languageId' => $languageId, 'nameTemplate' => $nameTemplate, 'showLogin' => $showLogin, 'pathToUser' => $pathToUser, ]); $commentFormatted = [ 'LOG_DATE' => $commentDateTime->toString(), "LOG_DATE_FORMAT" => $comment["LOG_DATE_FORMAT"], 'LOG_DATE_DAY' => convertTimeStamp($timestamp, 'SHORT'), 'LOG_TIME_FORMAT' => $timeFormatted, 'MESSAGE' => $commentText, 'MESSAGE_FORMAT' => $commentText, 'CREATED_BY' => $createdBy, 'AVATAR_SRC' => \CSocNetLogTools::formatEvent_CreateAvatar($authorFields, [ 'AVATAR_SIZE' => $avatarSize, ], ''), 'USER_ID' => $commentAuthorId, ]; if ( empty($entityXmlId) && $commentProvider->getContentTypeId() === Livefeed\ForumPost::CONTENT_TYPE_ID ) { $feedParams = $commentProvider->getFeedParams(); if (!empty($feedParams['xml_id'])) { $entityXmlId = $feedParams['xml_id']; } } if (empty($entityXmlId)) { return; } $rights = [ 'COMMENT_RIGHTS_EDIT' => 'N', 'COMMENT_RIGHTS_DELETE' => 'N', 'COMMENT_RIGHTS_CREATETASK' => 'N' ]; $records = static::getLiveCommentRecords([ 'commentId' => $commentId, 'ratingTypeId' => $ratingTypeId, 'timestamp' => $timestamp, 'author' => [ 'ID' => $authorFields['ID'], 'NAME' => $authorFields['NAME'], 'LAST_NAME' => $authorFields['LAST_NAME'], 'SECOND_NAME' => $authorFields['SECOND_NAME'], 'PERSONAL_GENDER' => $authorFields['PERSONAL_GENDER'], 'AVATAR' => $commentFormatted['AVATAR_SRC'], ], 'uf' => $comment['UF'], 'ufFormatted' => $commentFormatted['UF'], 'postMessageTextOriginal' => $comment['~MESSAGE'], 'postMessageTextFormatted' => $commentFormatted['MESSAGE_FORMAT'], 'mobileMessage' => $commentText, 'aux' => ($params['aux'] ?? ''), 'auxLiveParams' => ($params['auxLiveParams'] ?? []), ]); /* $viewUrl = (string)($comment['EVENT']['URL'] ?? ''); if (empty($viewUrl)) { $pathToLogEntry = (string)($params['PATH_TO_LOG_ENTRY'] ?? ''); if (!empty($pathToLogEntry)) { $viewUrl = \CComponentEngine::makePathFromTemplate( $pathToLogEntry, [ 'log_id' => $logEntry['ID'] ] ) . (mb_strpos($pathToLogEntry, '?') === false ? '?' : '&') . 'commentId=#ID#'; } } */ $res = static::sendLiveComment([ 'ratingTypeId' => $ratingTypeId, 'entityXMLId' => $entityXmlId, 'postContentTypeId' => $postContentTypeId, 'commentContentTypeId' => $commentContentTypeId, 'records' => $records, 'rights' => $rights, 'commentId' => $commentId, 'action' => 'REPLY', 'urlList' => [ // 'view' => $viewUrl, // 'edit' => "__logEditComment('" . $entityXMLId . "', '#ID#', '" . $logEntry["ID"] . "');", // 'delete' => '/bitrix/components/bitrix/socialnetwork.log.entry/ajax.php?lang=' . $params['LANGUAGE_ID'] . '&action=delete_comment&delete_comment_id=#ID#&post_id=' . $logEntry['ID'] . '&site=' . $params['SITE_ID'], ], 'avatarSize' => $avatarSize, 'nameTemplate' => $nameTemplate, // 'dateTimeFormat' => $params['DATE_TIME_FORMAT'], ]); } private static function getAuthorData(array $params = []): array { $userId = (int)($params['userId'] ?? 0); if ($userId > 0) { $result = [ 'ID' => $userId ]; $res = Main\UserTable::getList([ 'filter' => [ 'ID' => $userId, ], 'select' => [ 'ID', 'NAME', 'LAST_NAME', 'SECOND_NAME', 'LOGIN', 'PERSONAL_PHOTO', 'PERSONAL_GENDER' ] ]); if ($userFields = $res->fetch()) { $result = $userFields; } } else { $result = []; } return $result; } private static function getCreatedByData(array $params = []): array { $userFields = (array)($params['userFields'] ?? []); $languageId = ($params['languageId'] ?? null); $nameTemplate = (string)($params['nameTemplate'] ?? ''); $showLogin = (string)($params['showLogin'] ?? 'N'); $pathToUser = (string)($params['pathToUser'] ?? ''); if (!empty($userFields)) { $result = [ 'FORMATTED' => \CUser::formatName($nameTemplate, $userFields, ($showLogin !== 'N')), 'URL' => \CComponentEngine::makePathFromTemplate( $pathToUser, [ 'user_id' => $userFields['ID'], 'id' => $userFields['ID'], ] ) ]; } else { $result = [ 'FORMATTED' => Loc::getMessage('SONET_HELPER_CREATED_BY_ANONYMOUS', false, $languageId) ]; } return $result; } private static function getTimeFormat($siteTimeFormat = ''): string { if (empty($siteTimeFormat)) { $siteTimeFormat = \CSite::getTimeFormat(); } return ( mb_stripos($siteTimeFormat, 'a') || ( $siteTimeFormat === 'FULL' && ( mb_strpos(FORMAT_DATETIME, 'T') !== false || mb_strpos(FORMAT_DATETIME, 'TT') !== false ) ) ? (mb_strpos(FORMAT_DATETIME, 'TT') !== false ? 'H:MI TT' : 'H:MI T') : 'HH:MI' ); } private static function getLiveCommentRecords(array $params = []): array { $commentId = (int)($params['commentId'] ?? 0); $ratingTypeId = (string)($params['ratingTypeId'] ?? ''); $timestamp = (int)($params['timestamp'] ?? 0); $author = (array)($params['author'] ?? []); $uf = (array)($params['uf'] ?? []); $ufFormatted = (string)($params['ufFormatted'] ?? ''); $postMessageTextOriginal = (string)($params['postMessageTextOriginal'] ?? ''); $postMessageTextFormatted = (string)($params['postMessageTextFormatted'] ?? ''); $mobileMessage = (string)($params['mobileMessage'] ?? ''); $aux = (string)($params['aux'] ?? ''); $auxLiveParams = (array)($params['auxLiveParams'] ?? []); $records = [ $commentId => [ 'ID' => $commentId, 'RATING_VOTE_ID' => $ratingTypeId . '_' . $commentId . '-' . (time() + random_int(0, 1000)), 'APPROVED' => 'Y', 'POST_TIMESTAMP' => $timestamp, 'AUTHOR' => $author, 'FILES' => false, 'UF' => $uf, '~POST_MESSAGE_TEXT' => $postMessageTextOriginal, 'WEB' => [ 'CLASSNAME' => '', 'POST_MESSAGE_TEXT' => $postMessageTextFormatted, 'AFTER' => $ufFormatted, ], 'MOBILE' => [ 'CLASSNAME' => '', 'POST_MESSAGE_TEXT' => $mobileMessage ], 'AUX' => $aux, 'AUX_LIVE_PARAMS' => $auxLiveParams, ] ]; if ( !empty($uf) && !empty($uf['UF_SONET_COM_DOC']) && !empty($uf['UF_SONET_COM_DOC']['VALUE']) ) { $inlineDiskAttachedObjectIdImageList = self::getInlineDiskImages([ 'text' => $postMessageTextOriginal, 'commentId' => $commentId, ]); if (!empty($inlineDiskAttachedObjectIdImageList)) { $records[$commentId]['WEB']['UF'] = $records[$commentId]['UF']; $records[$commentId]['MOBILE']['UF'] = $records[$commentId]['UF']; $records[$commentId]['MOBILE']['UF']['UF_SONET_COM_DOC']['VALUE'] = array_diff($records[$commentId]['MOBILE']['UF']['UF_SONET_COM_DOC']['VALUE'], $inlineDiskAttachedObjectIdImageList); } } return $records; } private static function sendLiveComment(array $params = []): array { global $APPLICATION; $ratingTypeId = (string)($params['ratingTypeId'] ?? ''); $entityXMLId = (string)($params['entityXMLId'] ?? ''); $postContentTypeId = (string)($params['postContentTypeId'] ?? ''); $commentContentTypeId = (string)($params['commentContentTypeId'] ?? ''); $records = (array)($params['records'] ?? []); $rights = (array)($params['rights'] ?? []); $commentId = (int)($params['commentId'] ?? 0); $action = (string)($params['action'] ?? ''); $urlList = (array)($params['urlList'] ?? []); $avatarSize = (int)($params['avatarSize'] ?? 0); $nameTemplate = (string)($params['nameTemplate'] ?? ''); $showLogin = (isset($params['showLogin']) && $params['showLogin'] === 'Y' ? 'Y' : 'N'); $dateTimeFormat = (string)($params['dateTimeFormat'] ?? ''); return $APPLICATION->includeComponent( 'bitrix:main.post.list', '', [ 'TEMPLATE_ID' => '', 'RATING_TYPE_ID' => $ratingTypeId, 'ENTITY_XML_ID' => $entityXMLId, 'POST_CONTENT_TYPE_ID' => $postContentTypeId, 'COMMENT_CONTENT_TYPE_ID' => $commentContentTypeId, 'RECORDS' => $records, 'NAV_STRING' => '', 'NAV_RESULT' => '', 'PREORDER' => "N", 'RIGHTS' => [ 'MODERATE' => 'N', 'EDIT' => $rights['COMMENT_RIGHTS_EDIT'], 'DELETE' => $rights['COMMENT_RIGHTS_DELETE'], 'CREATETASK' => $rights['COMMENT_RIGHTS_CREATETASK'], ], 'VISIBLE_RECORDS_COUNT' => 1, 'ERROR_MESSAGE' => '', 'OK_MESSAGE' => '', 'RESULT' => $commentId, 'PUSH&PULL' => [ 'ACTION' => $action, 'ID' => $commentId ], 'MODE' => 'PULL_MESSAGE', 'VIEW_URL' => ($urlList['view'] ?? ''), 'EDIT_URL' => ($urlList['edit'] ?? ''), 'MODERATE_URL' => '', 'DELETE_URL' => ($urlList['delete'] ?? ''), 'AUTHOR_URL' => '', 'AVATAR_SIZE' => $avatarSize, 'NAME_TEMPLATE' => $nameTemplate, 'SHOW_LOGIN' => $showLogin, 'DATE_TIME_FORMAT' => $dateTimeFormat, 'LAZYLOAD' => 'N', 'NOTIFY_TAG' => '', 'NOTIFY_TEXT' => '', 'SHOW_MINIMIZED' => 'Y', 'SHOW_POST_FORM' => 'Y', 'IMAGE_SIZE' => '', 'mfi' => '', ], [], null ); } private static function getInlineDiskImages(array $params = []): array { $result = []; $text = (string)($params['text'] ?? ''); $commentId = (int)($params['commentId'] ?? 0); if ( $text === '' || $commentId <= 0 || !ModuleManager::isModuleInstalled('disk') ) { return $result; } $inlineDiskObjectIdList = []; $inlineDiskAttachedObjectIdList = []; // parse inline disk object ids if (preg_match_all('#\\[disk file id=(n\\d+)\\]#is' . BX_UTF_PCRE_MODIFIER, $text, $matches)) { $inlineDiskObjectIdList = array_map(function($a) { return (int)mb_substr($a, 1); }, $matches[1]); } // parse inline disk attached object ids if (preg_match_all('#\\[disk file id=(\\d+)\\]#is' . BX_UTF_PCRE_MODIFIER, $text, $matches)) { $inlineDiskAttachedObjectIdList = array_map(function($a) { return (int)$a; }, $matches[1]); } if ( ( empty($inlineDiskObjectIdList) && empty($inlineDiskAttachedObjectIdList) ) || !Loader::includeModule('disk') ) { return $result; } $filter = [ '=OBJECT.TYPE_FILE' => TypeFile::IMAGE ]; $subFilter = []; if (!empty($inlineDiskObjectIdList)) { $subFilter['@OBJECT_ID'] = $inlineDiskObjectIdList; } elseif (!empty($inlineDiskAttachedObjectIdList)) { $subFilter['@ID'] = $inlineDiskAttachedObjectIdList; } if(count($subFilter) > 1) { $subFilter['LOGIC'] = 'OR'; $filter[] = $subFilter; } else { $filter = array_merge($filter, $subFilter); } $res = \Bitrix\Disk\Internals\AttachedObjectTable::getList([ 'filter' => $filter, 'select' => array('ID', 'ENTITY_ID') ]); while ($attachedObjectFields = $res->fetch()) { if ((int)$attachedObjectFields['ENTITY_ID'] === $commentId) { $result[] = (int)$attachedObjectFields['ID']; } } return $result; } public static function fillSelectedUsersToInvite($HTTPPost, $componentParams, &$componentResult): void { if ( empty($HTTPPost["SPERM"]) || empty($HTTPPost["SPERM"]["UE"]) || !is_array($HTTPPost["SPERM"]["UE"]) ) { return; } $nameFormat = \CSite::getNameFormat(false); foreach ($HTTPPost["SPERM"]["UE"] as $invitedEmail) { $name = (!empty($HTTPPost["INVITED_USER_NAME"][$invitedEmail]) ? $HTTPPost["INVITED_USER_NAME"][$invitedEmail] : ''); $lastName = (!empty($HTTPPost["INVITED_USER_LAST_NAME"][$invitedEmail]) ? $HTTPPost["INVITED_USER_LAST_NAME"][$invitedEmail] : ''); $createCrmContact = ( !empty($HTTPPost["INVITED_USER_CREATE_CRM_CONTACT"][$invitedEmail]) && $HTTPPost["INVITED_USER_CREATE_CRM_CONTACT"][$invitedEmail] === 'Y' ); $userName = \CUser::formatName( empty($componentParams["NAME_TEMPLATE"]) ? $nameFormat : $componentParams["NAME_TEMPLATE"], array( 'NAME' => $name, 'LAST_NAME' => $lastName, 'LOGIN' => $invitedEmail ), true, false ); $componentResult["PostToShow"]["FEED_DESTINATION"]['USERS'][$invitedEmail] = [ 'id' => $invitedEmail, 'email' => $invitedEmail, 'showEmail' => 'Y', 'name' => $userName, 'isEmail' => 'Y', 'isCrmEmail' => ($createCrmContact ? 'Y' : 'N'), 'params' => [ 'name' => $name, 'lastName' => $lastName, 'createCrmContact' => $createCrmContact, ], ]; $componentResult["PostToShow"]["FEED_DESTINATION"]['SELECTED'][$invitedEmail] = 'users'; } } public static function processBlogPostNewMailUser(&$HTTPPost, &$componentResult): void { $newName = false; if (isset($HTTPPost['SONET_PERMS'])) { $HTTPPost['SPERM'] = $HTTPPost['SONET_PERMS']; $newName = true; } self::processBlogPostNewCrmContact($HTTPPost, $componentResult); if ($newName) { $HTTPPost['SONET_PERMS'] = $HTTPPost['SPERM']; unset($HTTPPost['SPERM']); } } private static function processUserEmail($params, &$errorText): array { $result = []; if ( !is_array($params) || empty($params['EMAIL']) || !check_email($params['EMAIL']) || !Loader::includeModule('mail') ) { return $result; } $userEmail = $params['EMAIL']; if ( empty($userEmail) || !check_email($userEmail) ) { return $result; } $res = \CUser::getList( 'ID', 'ASC', [ '=EMAIL' => $userEmail, '!EXTERNAL_AUTH_ID' => array_diff(\Bitrix\Main\UserTable::getExternalUserTypes(), [ 'email' ]), ], [ 'FIELDS' => [ 'ID', 'EXTERNAL_AUTH_ID', 'ACTIVE' ] ] ); $userId = false; while ( ($emailUser = $res->fetch()) && !$userId ) { if ( (int)$emailUser["ID"] > 0 && ( $emailUser["ACTIVE"] === "Y" || $emailUser["EXTERNAL_AUTH_ID"] === "email" ) ) { if ($emailUser["ACTIVE"] === "N") // email only { $user = new \CUser; $user->update($emailUser["ID"], [ 'ACTIVE' => 'Y' ]); } $userId = $emailUser['ID']; } } if ($userId) { $result = [ 'U'.$userId ]; } if (!$userId) { $userFields = array( 'EMAIL' => $userEmail, 'NAME' => ($params["NAME"] ?? ''), 'LAST_NAME' => ($params["LAST_NAME"] ?? '') ); if ( !empty($params["CRM_ENTITY"]) && Loader::includeModule('crm') ) { $userFields['UF'] = [ 'UF_USER_CRM_ENTITY' => $params["CRM_ENTITY"], ]; $res = \CCrmLiveFeedComponent::resolveLFEntityFromUF($params["CRM_ENTITY"]); if (!empty($res)) { [ $k, $v ] = $res; if ($k && $v) { $result[] = $k.$v; if ( $k === \CCrmLiveFeedEntity::Contact && ($contact = \CCrmContact::getById($v)) && (int)$contact['PHOTO'] > 0 ) { $userFields['PERSONAL_PHOTO_ID'] = (int)$contact['PHOTO']; } } } } elseif ( !empty($params["CREATE_CRM_CONTACT"]) && $params["CREATE_CRM_CONTACT"] === 'Y' && Loader::includeModule('crm') && ($contactId = \CCrmLiveFeedComponent::createContact($userFields)) ) { $userFields['UF'] = [ 'UF_USER_CRM_ENTITY' => 'C_'.$contactId ]; $result[] = "CRMCONTACT".$contactId; } // invite extranet user by email $userId = \Bitrix\Mail\User::create($userFields); $errorMessage = false; if ( is_object($userId) && $userId->LAST_ERROR <> '' ) { $errorMessage = $userId->LAST_ERROR; } if ( !$errorMessage && (int)$userId > 0 ) { $result[] = "U".$userId; } else { $errorText = $errorMessage; } } if ( !is_object($userId) && (int)$userId > 0 ) { \Bitrix\Main\UI\Selector\Entities::save([ 'context' => (isset($params['CONTEXT']) && $params['CONTEXT'] <> '' ? $params['CONTEXT'] : 'BLOG_POST'), 'code' => 'U'.$userId ]); if (Loader::includeModule('intranet') && class_exists('\Bitrix\Intranet\Integration\Mail\EmailUser')) { \Bitrix\Intranet\Integration\Mail\EmailUser::invite($userId); } } return $result; } public static function processBlogPostNewMailUserDestinations(&$destinationList) { foreach($destinationList as $key => $code) { if (preg_match('/^UE(.+)$/i', $code, $matches)) { $userEmail = $matches[1]; $errorText = ''; $destRes = self::processUserEmail(array( 'EMAIL' => $userEmail, 'CONTEXT' => 'BLOG_POST' ), $errorText); if ( !empty($destRes) && is_array($destRes) ) { unset($destinationList[$key]); $destinationList = array_merge($destinationList, $destRes); } } } } public static function processBlogPostNewCrmContact(&$HTTPPost, &$componentResult) { $USent = ( isset($HTTPPost["SPERM"]["U"]) && is_array($HTTPPost["SPERM"]["U"]) && !empty($HTTPPost["SPERM"]["U"]) ); $UESent = ( $componentResult["ALLOW_EMAIL_INVITATION"] && isset($HTTPPost["SPERM"]["UE"]) && is_array($HTTPPost["SPERM"]["UE"]) && !empty($HTTPPost["SPERM"]["UE"]) ); if ( ($USent || $UESent) && Loader::includeModule('mail') ) { if ( $USent && Loader::includeModule('crm') ) // process mail users/contacts { $userIdList = array(); foreach ($HTTPPost["SPERM"]["U"] as $code) { if (preg_match('/^U(\d+)$/i', $code, $matches)) { $userIdList[] = (int)$matches[1]; } } if (!empty($userIdList)) { $res = Main\UserTable::getList(array( 'filter' => array( 'ID' => $userIdList, '!=UF_USER_CRM_ENTITY' => false ), 'select' => array('ID', 'UF_USER_CRM_ENTITY') )); while ($user = $res->fetch()) { $livefeedCrmEntity = \CCrmLiveFeedComponent::resolveLFEntityFromUF($user['UF_USER_CRM_ENTITY']); if (!empty($livefeedCrmEntity)) { list($k, $v) = $livefeedCrmEntity; if ($k && $v) { if (!isset($HTTPPost["SPERM"][$k])) { $HTTPPost["SPERM"][$k] = array(); } $HTTPPost["SPERM"][$k][] = $k.$v; } } } } } if ($UESent) // process emails { foreach ($HTTPPost["SPERM"]["UE"] as $key => $userEmail) { if (!check_email($userEmail)) { continue; } $errorText = ''; $destRes = self::processUserEmail([ 'EMAIL' => $userEmail, 'NAME' => ( isset($HTTPPost["INVITED_USER_NAME"]) && isset($HTTPPost["INVITED_USER_NAME"][$userEmail]) ? $HTTPPost["INVITED_USER_NAME"][$userEmail] : '' ), 'LAST_NAME' => ( isset($HTTPPost["INVITED_USER_LAST_NAME"]) && isset($HTTPPost["INVITED_USER_LAST_NAME"][$userEmail]) ? $HTTPPost["INVITED_USER_LAST_NAME"][$userEmail] : '' ), 'CRM_ENTITY' => ( isset($HTTPPost["INVITED_USER_CRM_ENTITY"]) && isset($HTTPPost["INVITED_USER_CRM_ENTITY"][$userEmail]) ? $HTTPPost["INVITED_USER_CRM_ENTITY"][$userEmail] : '' ), "CREATE_CRM_CONTACT" => ( isset($HTTPPost["INVITED_USER_CREATE_CRM_CONTACT"]) && isset($HTTPPost["INVITED_USER_CREATE_CRM_CONTACT"][$userEmail]) ? $HTTPPost["INVITED_USER_CREATE_CRM_CONTACT"][$userEmail] : 'N' ), 'CONTEXT' => 'BLOG_POST' ], $errorText); foreach($destRes as $code) { if (preg_match('/^U(\d+)$/i', $code, $matches)) { $HTTPPost["SPERM"]["U"][] = $code; } elseif ( Loader::includeModule('crm') && (preg_match('/^CRM(CONTACT|COMPANY|LEAD|DEAL)(\d+)$/i', $code, $matches)) ) { if (!isset($HTTPPost["SPERM"]["CRM".$matches[1]])) { $HTTPPost["SPERM"]["CRM".$matches[1]] = array(); } $HTTPPost["SPERM"]["CRM".$matches[1]][] = $code; } } if (!empty($errorText)) { $componentResult["ERROR_MESSAGE"] .= $errorText; } } // unset($HTTPPost["SPERM"]["UE"]); } } } public static function getUserSonetGroupIdList($userId = false, $siteId = false) { $result = array(); if ((int)$userId <= 0) { global $USER; $userId = (int)$USER->getId(); } if (!$siteId) { $siteId = SITE_ID; } $currentCache = \Bitrix\Main\Data\Cache::createInstance(); $cacheTtl = defined("BX_COMP_MANAGED_CACHE") ? 3153600 : 3600*4; $cacheId = 'user_group_member'.$siteId.'_'.$userId; $cacheDir = '/sonet/user_group_member/'.$siteId.'/'.$userId; if($currentCache->startDataCache($cacheTtl, $cacheId, $cacheDir)) { global $CACHE_MANAGER; $res = UserToGroupTable::getList(array( 'filter' => array( '<=ROLE' => UserToGroupTable::ROLE_USER, '=USER_ID' => $userId, '=GROUP.ACTIVE' => 'Y', '=GROUP.WorkgroupSite:GROUP.SITE_ID' => $siteId ), 'select' => array('GROUP_ID') )); while ($record = $res->fetch()) { $result[] = $record["GROUP_ID"]; } if(defined("BX_COMP_MANAGED_CACHE")) { $CACHE_MANAGER->startTagCache($cacheDir); $CACHE_MANAGER->registerTag("sonet_user2group_U".$userId); $CACHE_MANAGER->endTagCache(); } $currentCache->endDataCache($result); } else { $result = $currentCache->getVars(); } return $result; } public static function getAllowToAllDestination($userId = 0) { global $USER; $userId = (int)$userId; if ($userId <= 0) { $userId = (int)$USER->getId(); } $allowToAll = (Option::get("socialnetwork", "allow_livefeed_toall", "Y") === "Y"); if ($allowToAll) { $toAllRightsList = unserialize(Option::get("socialnetwork", "livefeed_toall_rights", 'a:1:{i:0;s:2:"AU";}'), [ 'allowed_classes' => false ]); if (!$toAllRightsList) { $toAllRightsList = array("AU"); } $userGroupCodeList = array_merge(array("AU"), \CAccess::getUserCodesArray($userId)); if (count(array_intersect($toAllRightsList, $userGroupCodeList)) <= 0) { $allowToAll = false; } } return $allowToAll; } public static function getLivefeedStepper() { $res = array(); if (ModuleManager::isModuleInstalled('blog')) { $res["blog"] = array('Bitrix\Blog\Update\LivefeedIndexPost', 'Bitrix\Blog\Update\LivefeedIndexComment'); } if (ModuleManager::isModuleInstalled('tasks')) { $res["tasks"] = array('Bitrix\Tasks\Update\LivefeedIndexTask'); } if (ModuleManager::isModuleInstalled('calendar')) { $res["calendar"] = array('Bitrix\Calendar\Update\LivefeedIndexCalendar'); } if (ModuleManager::isModuleInstalled('forum')) { $res["forum"] = array('Bitrix\Forum\Update\LivefeedIndexMessage', 'Bitrix\Forum\Update\LivefeedIndexComment'); } if (ModuleManager::isModuleInstalled('xdimport')) { $res["xdimport"] = array('Bitrix\XDImport\Update\LivefeedIndexLog', 'Bitrix\XDImport\Update\LivefeedIndexComment'); } if (ModuleManager::isModuleInstalled('wiki')) { $res["wiki"] = array('Bitrix\Wiki\Update\LivefeedIndexLog', 'Bitrix\Wiki\Update\LivefeedIndexComment'); } if (!empty($res)) { echo Stepper::getHtml($res, Loc::getMessage(ModuleManager::isModuleInstalled('intranet') ? 'SONET_HELPER_STEPPER_LIVEFEED2': 'SONET_HELPER_STEPPER_LIVEFEED')); } } public static function checkProfileRedirect($userId = 0) { $userId = (int)$userId; if ($userId <= 0) { return; } $select = array('ID', 'EXTERNAL_AUTH_ID'); if (ModuleManager::isModuleInstalled('crm')) { $select[] = 'UF_USER_CRM_ENTITY'; } $res = Main\UserTable::getList(array( 'filter' => array( '=ID' => $userId ), 'select' => $select )); if ($userFields = $res->fetch()) { $event = new Main\Event( 'socialnetwork', 'onUserProfileRedirectGetUrl', array( 'userFields' => $userFields ) ); $event->send(); foreach ($event->getResults() as $eventResult) { if ($eventResult->getType() === \Bitrix\Main\EventResult::SUCCESS) { $eventParams = $eventResult->getParameters(); if ( is_array($eventParams) && isset($eventParams['url']) ) { LocalRedirect($eventParams['url']); } break; } } } } // used when video transform public static function getBlogPostLimitedViewStatus($params = array()) { $result = false; $logId = ( is_array($params) && !empty($params['logId']) && (int)$params['logId'] > 0 ? (int)$params['logId'] : 0 ); if ($logId <= 0) { return $result; } if ($logItem = Log::getById($logId)) { $logItemFields = $logItem->getFields(); if ( isset($logItemFields['TRANSFORM']) && $logItemFields['TRANSFORM'] === "Y" ) { $result = true; } } return $result; } public static function setBlogPostLimitedViewStatus($params = array()) { static $extranetSiteId = null; $result = false; $show = ( is_array($params) && isset($params['show']) && $params['show'] === true ); $postId = ( is_array($params) && !empty($params['postId']) && (int)$params['postId'] > 0 ? (int)$params['postId'] : 0 ); if ( $postId <= 0 || !Loader::includeModule('blog') ) { return $result; } if ($show) { $liveFeedEntity = Livefeed\Provider::init(array( 'ENTITY_TYPE' => 'BLOG_POST', 'ENTITY_ID' => $postId, )); $logId = $liveFeedEntity->getLogId(); if (!self::getBlogPostLimitedViewStatus(array( 'logId' => $logId ))) { return $result; } $post = Post::getById($postId); $postFields = $post->getFields(); $socnetPerms = self::getBlogPostSocNetPerms(array( 'postId' => $postId, 'authorId' => $postFields["AUTHOR_ID"] )); \CSocNetLogRights::deleteByLogID($logId); \CSocNetLogRights::add($logId, $socnetPerms, true, false); LogTable::update($logId, array( 'LOG_UPDATE' => new SqlExpression(Application::getConnection()->getSqlHelper()->getCurrentDateTimeFunction()), 'TRANSFORM' => 'N' )); if (\Bitrix\Main\Loader::includeModule('crm')) { $logItem = Log::getById($logId); \CCrmLiveFeedComponent::processCrmBlogPostRights($logId, $logItem->getFields(), $postFields, 'new'); } \Bitrix\Blog\Integration\Socialnetwork\CounterPost::increment(array( 'socnetPerms' => $socnetPerms, 'logId' => $logId, 'logEventId' => $liveFeedEntity->getEventId() )); $logSiteIdList = array(); $resSite = \CSocNetLog::getSite($logId); while($logSite = $resSite->fetch()) { $logSiteIdList[] = $logSite["LID"]; } if ( $extranetSiteId === null && Loader::includeModule('extranet') ) { $extranetSiteId = \CExtranet::getExtranetSiteID(); } $siteId = false; foreach($logSiteIdList as $logSiteId) { if ($logSiteId != $extranetSiteId) { $siteId = $logSiteId; break; } } if (!$siteId) { $siteId = \CSite::getDefSite(); } $postUrl = \CComponentEngine::makePathFromTemplate( \Bitrix\Socialnetwork\Helper\Path::get('userblogpost_page', $siteId), array( "post_id" => $postId, "user_id" => $postFields["AUTHOR_ID"] ) ); $notificationParamsList = array( 'post' => array( 'ID' => $postFields["ID"], 'TITLE' => $postFields["TITLE"], 'AUTHOR_ID' => $postFields["AUTHOR_ID"] ), 'siteId' => $siteId, 'postUrl' => $postUrl, 'socnetRights' => $socnetPerms, ); $notificationParamsList['mentionList'] = Mention::getUserIds($postFields['DETAIL_TEXT']); self::notifyBlogPostCreated($notificationParamsList); if ( !isset($params['notifyAuthor']) || $params['notifyAuthor'] ) { self::notifyAuthorOnSetBlogPostLimitedViewStatusShow(array( 'POST_ID' => $postId, 'POST_FIELDS' => $postFields, 'POST_URL' => $postUrl, 'LOG_ID' => $logId, 'SITE_ID' => $siteId )); } BXClearCache(true, self::getBlogPostCacheDir(array( 'TYPE' => 'post', 'POST_ID' => $postId ))); } $result = true; return $result; } private static function notifyAuthorOnSetBlogPostLimitedViewStatusShow($params = array()) { $postId = $params['POST_ID']; $postFields = $params['POST_FIELDS']; $postUrl = $params['POST_URL']; $logId = $params['LOG_ID']; $siteId = $params['SITE_ID']; if (Loader::includeModule('im')) { $authorPostUrl = $postUrl; if (ModuleManager::isModuleInstalled("extranet")) { $tmp = \CSocNetLogTools::processPath( array( "URL" => $authorPostUrl, ), $postFields["AUTHOR_ID"], $siteId ); $authorPostUrl = $tmp["URLS"]["URL"]; $serverName = ( mb_strpos($authorPostUrl, "http://") === 0 || mb_strpos($authorPostUrl, "https://") === 0 ? "" : $tmp["SERVER_NAME"] ); } $messageFields = array( "MESSAGE_TYPE" => IM_MESSAGE_SYSTEM, "TO_USER_ID" => $postFields["AUTHOR_ID"], "FROM_USER_ID" => $postFields["AUTHOR_ID"], "NOTIFY_TYPE" => IM_NOTIFY_SYSTEM, "NOTIFY_ANSWER" => "N", "NOTIFY_MODULE" => "socialnetwork", "NOTIFY_EVENT" => "transform", "NOTIFY_TAG" => "SONET|BLOG_POST_CONVERT|".$postId, "PARSE_LINK" => "N", "LOG_ID" => $logId, "NOTIFY_MESSAGE" => Loc::getMessage('SONET_HELPER_VIDEO_CONVERSION_COMPLETED', array( '#POST_TITLE#' => '<a href="'.$authorPostUrl.'" class="bx-notifier-item-action">'.htmlspecialcharsbx($postFields["TITLE"]).'</a>' )), "NOTIFY_MESSAGE_OUT" => Loc::getMessage('SONET_HELPER_VIDEO_CONVERSION_COMPLETED', array( '#POST_TITLE#' => htmlspecialcharsbx($postFields["TITLE"]), ))." ".$serverName.$authorPostUrl, ); $messageFields['PUSH_MESSAGE'] = $messageFields['NOTIFY_MESSAGE']; $messageFields['PUSH_PARAMS'] = array( 'ACTION' => 'transform', 'TAG' => $messageFields['NOTIFY_TAG'] ); \CIMNotify::add($messageFields); } } public static function getBlogPostSocNetPerms($params = array()) { $result = array(); $postId = ( is_array($params) && !empty($params['postId']) && (int)$params['postId'] > 0 ? (int)$params['postId'] : 0 ); $authorId = ( is_array($params) && !empty($params['authorId']) && (int)$params['authorId'] > 0 ? (int)$params['authorId'] : 0 ); if ($postId <= 0) { return $result; } if ($authorId <= 0) { $blogPostFields = \CBlogPost::getByID($postId); $authorId = (int)$blogPostFields["AUTHOR_ID"]; } if ($authorId <= 0) { return $result; } $result = \CBlogPost::getSocNetPermsCode($postId); $profileBlogPost = false; foreach($result as $perm) { if (preg_match('/^UP(\d+)$/', $perm, $matches)) { $profileBlogPost = true; break; } } if (!$profileBlogPost) { if (!in_array("U".$authorId, $result, true)) { $result[] = "U".$authorId; } $result[] = "SA"; // socnet admin if ( in_array("AU", $result, true) || in_array("G2", $result, true) ) { $socnetPermsAdd = array(); foreach ($result as $perm) { if (preg_match('/^SG(\d+)$/', $perm, $matches)) { if ( !in_array("SG".$matches[1]."_".UserToGroupTable::ROLE_USER, $result, true) && !in_array("SG".$matches[1]."_".UserToGroupTable::ROLE_MODERATOR, $result, true) && !in_array("SG".$matches[1]."_".UserToGroupTable::ROLE_OWNER, $result, true) ) { $socnetPermsAdd[] = "SG".$matches[1]."_".$result; } } } if (count($socnetPermsAdd) > 0) { $result = array_merge($result, $socnetPermsAdd); } } } return $result; } public static function notifyBlogPostCreated($params = array()) { if (!Loader::includeModule('blog')) { return false; } $post = ( !empty($params) && is_array($params) && !empty($params['post']) && is_array($params['post']) ? $params['post'] : [] ); $siteId = ( !empty($params) && is_array($params) && !empty($params['siteId']) ? $params['siteId'] : \CSite::getDefSite() ); $postUrl = ( !empty($params) && is_array($params) && !empty($params['postUrl']) ? $params['postUrl'] : '' ); $socnetRights = ( !empty($params) && is_array($params) && !empty($params['socnetRights']) && is_array($params['socnetRights']) ? $params['socnetRights'] : [] ); $socnetRightsOld = ( !empty($params) && is_array($params) && !empty($params['socnetRightsOld']) && is_array($params['socnetRightsOld']) ? $params['socnetRightsOld'] : array( 'U' => [], 'SG' => [] ) ); $mentionListOld = ( !empty($params) && is_array($params) && !empty($params['mentionListOld']) && is_array($params['mentionListOld']) ? $params['mentionListOld'] : [] ); $mentionList = ( !empty($params) && is_array($params) && !empty($params['mentionList']) && is_array($params['mentionList']) ? $params['mentionList'] : [] ); $gratData = ( !empty($params) && is_array($params) && !empty($params['gratData']) && is_array($params['gratData']) ? $params['gratData'] : [] ); $IMNotificationFields = array( "TYPE" => "POST", "TITLE" => $post["TITLE"], "URL" => $postUrl, "ID" => $post["ID"], "FROM_USER_ID" => $post["AUTHOR_ID"], "TO_USER_ID" => array(), "TO_SOCNET_RIGHTS" => $socnetRights, "TO_SOCNET_RIGHTS_OLD" => $socnetRightsOld, "GRAT_DATA" => $gratData ); if (!empty($mentionListOld)) { $IMNotificationFields["MENTION_ID_OLD"] = $mentionListOld; } if (!empty($mentionList)) { $IMNotificationFields["MENTION_ID"] = $mentionList; } $userIdSentList = \CBlogPost::notifyIm($IMNotificationFields); if (!$userIdSentList) { $userIdSentList = []; } $userIdToMailList = []; if (!empty($socnetRights)) { \Bitrix\Blog\Broadcast::send(array( "EMAIL_FROM" => Option::get('main', 'email_from', 'nobody@nobody.com'), "SOCNET_RIGHTS" => $socnetRights, "SOCNET_RIGHTS_OLD" => $socnetRightsOld, "ENTITY_TYPE" => "POST", "ENTITY_ID" => $post["ID"], "AUTHOR_ID" => $post["AUTHOR_ID"], "URL" => $postUrl, 'EXCLUDE_USERS' => array_merge([ $post['AUTHOR_ID'] ], $userIdSentList), )); foreach ($socnetRights as $right) { if (mb_strpos($right, "U") === 0) { $rightUserId = (int)mb_substr($right, 1); if ( $rightUserId > 0 && empty($socnetRightsOld["U"][$rightUserId]) && $rightUserId !== (int)$post["AUTHOR_ID"] && !in_array($rightUserId, $userIdToMailList, true) ) { $userIdToMailList[] = $rightUserId; } } } } if (!empty($userIdToMailList)) { \CBlogPost::notifyMail([ "type" => "POST", "siteId" => $siteId, "userId" => $userIdToMailList, "authorId" => $post["AUTHOR_ID"], "postId" => $post["ID"], "postUrl" => \CComponentEngine::makePathFromTemplate( '/pub/post.php?post_id=#post_id#', [ "post_id" => $post["ID"], ] ), ]); } return true; } public static function getUserSEFUrl($params = array()) { list($siteId, $siteDir) = self::getSiteId($params); return Option::get('socialnetwork', 'user_page', $siteDir.'company/personal/', $siteId); } public static function getWorkgroupSEFUrl($params = []): string { list($siteId, $siteDir) = self::getSiteId($params); return Option::get('socialnetwork', 'workgroups_page', $siteDir.'workgroups/', $siteId); } public static function getSpacesSEFUrl($params = []): string { list($siteId, $siteDir) = self::getSiteId($params); return $siteDir . 'spaces/'; } private static function getSiteId($params = []): array { $siteId = ( is_array($params) && isset($params['siteId']) ? $params['siteId'] : false ); $siteDir = SITE_DIR; if ($siteId) { $res = \CSite::getById($siteId); if ($site = $res->fetch()) { $siteDir = $site['DIR']; } } return [$siteId, $siteDir]; } public static function convertBlogPostPermToDestinationList($params, &$resultFields) { global $USER; $result = array(); if (!Loader::includeModule('blog')) { return $result; } $postId = ( isset($params['POST_ID']) && (int)$params['POST_ID'] > 0 ? (int)$params['POST_ID'] : false ); $postFields = array(); if ($postId) { $postFields = \Bitrix\Blog\Item\Post::getById($postId)->getFields(); } $authorId = ( !$postId && isset($params['AUTHOR_ID']) && (int)$params['AUTHOR_ID'] > 0 ? (int)$params['AUTHOR_ID'] : $postFields['AUTHOR_ID'] ); $extranetUser = ( $params['IS_EXTRANET_USER'] ?? self::isCurrentUserExtranet([ 'siteId' => SITE_ID, 'userId' => $USER->getId(), ]) ); $siteId = ( !empty($params['SITE_ID']) ? $params['SITE_ID'] : SITE_ID ); $socNetPermsListOld = array(); if ($postId > 0) { $socNetPermsListOld = \CBlogPost::getSocNetPerms($postId); } $authorInDest = ( !empty($postFields) && !empty($postFields['AUTHOR_ID']) && !empty($socNetPermsListOld) && !empty($socNetPermsListOld['U']) && isset($socNetPermsListOld['U'][$postFields['AUTHOR_ID']]) && in_array('U' . $postFields['AUTHOR_ID'], $socNetPermsListOld['U'][$postFields['AUTHOR_ID']], true) ); $permList = ( isset($params['PERM']) && is_array($params['PERM']) ? $params['PERM'] : array() ); $allowToAll = self::getAllowToAllDestination(); if( empty($permList) && isset($params["IS_REST"]) && $params["IS_REST"] && $allowToAll ) { $permList = array("UA" => array("UA")); } foreach ($permList as $v => $k) { if ( $v <> '' && is_array($k) && !empty($k) ) { foreach ($k as $vv) { if ( $vv <> '' && ( empty($postFields['AUTHOR_ID']) || $vv !== 'U'.$postFields['AUTHOR_ID'] || $authorInDest ) ) { $result[] = $vv; } } } } $result = self::checkBlogPostDestinationList(array( 'DEST' => $result, 'SITE_ID' => $siteId, 'AUTHOR_ID' => $authorId, 'IS_EXTRANET_USER' => $extranetUser, 'POST_ID' => $postId ), $resultFields); return $result; } public static function checkBlogPostDestinationList($params, &$resultFields) { global $USER; $destinationList = ( isset($params["DEST"]) && is_array($params["DEST"]) ? $params["DEST"] : array() ); $siteId = ( !empty($params['SITE_ID']) ? $params['SITE_ID'] : SITE_ID ); $currentUserId = $USER->getId(); if (!$currentUserId) { return false; } $extranetUser = ( $params['IS_EXTRANET_USER'] ?? self::isCurrentUserExtranet([ 'siteId' => SITE_ID, 'userId' => $USER->getId() ]) ); $postId = ( isset($params['POST_ID']) && (int)$params['POST_ID'] > 0 ? (int)$params['POST_ID'] : false ); $postFields = []; $oldSonetGroupIdList = []; if ($postId) { $socNetPermsListOld = \CBlogPost::getSocNetPerms($postId); $postFields = \Bitrix\Blog\Item\Post::getById($postId)->getFields(); if (!empty($socNetPermsListOld['SG'])) { $oldSonetGroupIdList = array_keys($socNetPermsListOld['SG']); } } $userAdmin = \CSocNetUser::isUserModuleAdmin($currentUserId, $siteId); $allowToAll = self::getAllowToAllDestination(); $newSonetGroupIdList = []; $newUserIdList = []; foreach($destinationList as $code) { if (preg_match('/^SG(\d+)/i', $code, $matches)) { $newSonetGroupIdList[] = (int)$matches[1]; } elseif (preg_match('/^U(\d+)/i', $code, $matches)) { $newUserIdList[] = (int)$matches[1]; } } if (!empty($newSonetGroupIdList)) { $oneSG = false; $firstSG = true; $premoderateSGList = []; $canPublish = true; foreach ($newSonetGroupIdList as $groupId) { if ( !empty($postFields) && $postFields["PUBLISH_STATUS"] === BLOG_PUBLISH_STATUS_PUBLISH && in_array($groupId, $oldSonetGroupIdList) ) { continue; } $canPublishToGroup = ( $userAdmin || \CSocNetFeaturesPerms::canPerformOperation($currentUserId, SONET_ENTITY_GROUP, $groupId, 'blog', 'write_post') || \CSocNetFeaturesPerms::canPerformOperation($currentUserId, SONET_ENTITY_GROUP, $groupId, 'blog', 'full_post') || \CSocNetFeaturesPerms::canPerformOperation($currentUserId, SONET_ENTITY_GROUP, $groupId, 'blog', 'moderate_post') ); $canPremoderateToGroup = \CSocNetFeaturesPerms::canPerformOperation($currentUserId, SONET_ENTITY_GROUP, $groupId, 'blog', 'premoderate_post'); if ( !$canPublishToGroup && $canPremoderateToGroup ) { $premoderateSGList[] = $groupId; } $canPublish = ( $canPublish && $canPublishToGroup ); if($firstSG) { $oneSG = true; $firstSG = false; } else { $oneSG = false; } } if (!$canPublish) { if (!empty($premoderateSGList)) { if ($oneSG) { if ($resultFields['PUBLISH_STATUS'] === BLOG_PUBLISH_STATUS_PUBLISH) { if (!$postId) // new post { $resultFields['PUBLISH_STATUS'] = BLOG_PUBLISH_STATUS_READY; } elseif ($postFields['PUBLISH_STATUS'] !== BLOG_PUBLISH_STATUS_PUBLISH) { $resultFields['PUBLISH_STATUS'] = $postFields['PUBLISH_STATUS']; } else { $resultFields['ERROR_MESSAGE'] = Loc::getMessage('SBPE_EXISTING_POST_PREMODERATION'); $resultFields['ERROR_MESSAGE_PUBLIC'] = $resultFields['ERROR_MESSAGE']; } } } else { $groupNameList = []; $groupUrl = Option::get('socialnetwork', 'workgroups_page', SITE_DIR.'workgroups/', SITE_ID).'group/#group_id#/'; $res = WorkgroupTable::getList([ 'filter' => [ '@ID' => $premoderateSGList ], 'select' => [ 'ID', 'NAME' ] ]); while ($groupFields = $res->fetch()) { $groupNameList[] = ( isset($params['MOBILE']) && $params['MOBILE'] === 'Y' ? $groupFields['NAME'] : '<a href="' . \CComponentEngine::makePathFromTemplate($groupUrl, [ 'group_id' => $groupFields['ID'] ]) . '">' . htmlspecialcharsEx($groupFields['NAME']) . '</a>' ); } $resultFields['ERROR_MESSAGE'] = Loc::getMessage('SBPE_MULTIPLE_PREMODERATION2', [ '#GROUPS_LIST#' => implode(', ', $groupNameList) ]); $resultFields['ERROR_MESSAGE_PUBLIC'] = $resultFields['ERROR_MESSAGE']; } } else { $resultFields['ERROR_MESSAGE'] = Loc::getMessage('SONET_HELPER_NO_PERMISSIONS'); } } } if ($extranetUser) { $destinationList = array_filter($destinationList, static function ($code) { return (!preg_match('/^(DR|D)(\d+)$/i', $code, $matches)); }); if ( !empty($newUserIdList) && Loader::includeModule('extranet') ) { $visibleUserIdList = \CExtranet::getMyGroupsUsersSimple(SITE_ID); if (!empty(array_diff($newUserIdList, $visibleUserIdList))) { $resultFields['ERROR_MESSAGE'] = Loc::getMessage('SONET_HELPER_NO_PERMISSIONS'); } } } if ( !$allowToAll && in_array("UA", $destinationList, true) ) { foreach ($destinationList as $key => $value) { if ($value === "UA") { unset($destinationList[$key]); break; } } } if ($extranetUser) { if ( empty($destinationList) || in_array("UA", $destinationList, true) ) { $resultFields["ERROR_MESSAGE"] .= Loc::getMessage("BLOG_BPE_EXTRANET_ERROR"); } } elseif (empty($destinationList)) { $resultFields["ERROR_MESSAGE"] .= Loc::getMessage("BLOG_BPE_DESTINATION_EMPTY"); } return $destinationList; } public static function getBlogPostCacheDir($params = array()) { static $allowedTypes = array( 'post_general', 'post', 'post_urlpreview', 'posts_popular', 'post_comments', 'posts_last', 'posts_last_blog' ); $result = false; if (!is_array($params)) { return $result; } $type = ($params['TYPE'] ?? false); if ( !$type || !in_array($type, $allowedTypes, true) ) { return $result; } $postId = ( isset($params['POST_ID']) && (int)$params['POST_ID'] > 0 ? (int)$params['POST_ID'] : false ); if ( !$postId && in_array($type, array('post_general', 'post', 'post_comments', 'post_urlpreview')) ) { return $result; } $siteId = ($params['SITE_ID'] ?? SITE_ID); switch($type) { case 'post': $result = "/blog/socnet_post/".(int)($postId / 100)."/".$postId."/"; break; case 'post_general': $result = "/blog/socnet_post/gen/".(int)($postId / 100)."/".$postId; break; case 'post_urlpreview': $result = "/blog/socnet_post/urlpreview/".(int)($postId / 100)."/".$postId; break; case 'posts_popular': $result = "/".$siteId."/blog/popular_posts/"; break; case 'posts_last': $result = "/".$siteId."/blog/last_messages_list/"; break; case 'posts_last_blog': $result = "/".$siteId."/blog/last_messages/"; break; case 'post_comments': $result = "/blog/comment/".(int)($postId / 100)."/".$postId."/"; break; default: $result = false; } return $result; } public static function getLivefeedRatingData($params = []) { global $USER; $result = []; $logIdList = ( !empty($params['logId']) ? $params['logId'] : [] ); if (!is_array($logIdList)) { $logIdList = [ $logIdList ]; } if (empty($logIdList)) { return $result; } $ratingId = \CRatings::getAuthorityRating(); if ((int)$ratingId <= 0) { return $result; } $result = array_fill_keys($logIdList, []); $topCount = ( isset($params['topCount']) ? (int)$params['topCount'] : 0 ); if ($topCount <= 0) { $topCount = 2; } if ($topCount > 5) { $topCount = 5; } $avatarSize = ( isset($params['avatarSize']) ? (int)$params['avatarSize'] : 100 ); $connection = Application::getConnection(); if (ModuleManager::isModuleInstalled('intranet')) { $res = $connection->query(' SELECT /*+ NO_DERIVED_CONDITION_PUSHDOWN() */ RS1.ENTITY_ID as USER_ID, SL.ID as LOG_ID, MAX(RS1.VOTES) as WEIGHT FROM b_rating_subordinate RS1, b_rating_vote RV1 INNER JOIN b_sonet_log SL ON SL.RATING_TYPE_ID = RV1.ENTITY_TYPE_ID AND SL.RATING_ENTITY_ID = RV1.ENTITY_ID AND SL.ID IN ('.implode(',', $logIdList).') WHERE RS1.ENTITY_ID = RV1.USER_ID AND RS1.RATING_ID = '.(int)$ratingId.' GROUP BY SL.ID, RS1.ENTITY_ID ORDER BY SL.ID, WEIGHT DESC '); } else { $res = $connection->query(' SELECT /*+ NO_DERIVED_CONDITION_PUSHDOWN() */ RV1.USER_ID as USER_ID, SL.ID as LOG_ID, RV1.VALUE as WEIGHT FROM b_rating_vote RV1 INNER JOIN b_sonet_log SL ON SL.RATING_TYPE_ID = RV1.ENTITY_TYPE_ID AND SL.RATING_ENTITY_ID = RV1.ENTITY_ID AND SL.ID IN ('.implode(',', $logIdList).') ORDER BY SL.ID, WEIGHT DESC '); } $userWeightData = []; $logUserData = []; $currentLogId = 0; $hasMine = false; $cnt = 0; while ($voteFields = $res->fetch()) { $voteUserId = (int)$voteFields['USER_ID']; $voteLogId = (int)$voteFields['LOG_ID']; if ( !$hasMine && $voteUserId === (int)$USER->getId() ) { $hasMine = true; } if ($voteLogId !== $currentLogId) { $cnt = 0; $hasMine = false; $logUserData[$voteLogId] = []; } $currentLogId = $voteLogId; if (in_array($voteUserId, $logUserData[$voteLogId], true)) { continue; } $cnt++; if ($cnt > ($hasMine ? $topCount+1 : $topCount)) { continue; } $logUserData[$voteLogId][] = $voteUserId; if (!isset($userWeightData[$voteUserId])) { $userWeightData[$voteUserId] = (float)$voteFields['WEIGHT']; } } $userData = []; if (!empty($userWeightData)) { $res = Main\UserTable::getList([ 'filter' => [ '@ID' => array_keys($userWeightData) ], 'select' => [ 'ID', 'NAME', 'LAST_NAME', 'SECOND_NAME', 'LOGIN', 'PERSONAL_PHOTO', 'PERSONAL_GENDER' ] ]); while ($userFields = $res->fetch()) { $userData[$userFields["ID"]] = [ 'NAME_FORMATTED' => \CUser::formatName( \CSite::getNameFormat(false), $userFields, true ), 'PERSONAL_PHOTO' => [ 'ID' => $userFields['PERSONAL_PHOTO'], 'SRC' => false ], 'PERSONAL_GENDER' => $userFields['PERSONAL_GENDER'] ]; if ((int)$userFields['PERSONAL_PHOTO'] > 0) { $imageFile = \CFile::getFileArray($userFields["PERSONAL_PHOTO"]); if ($imageFile !== false) { $file = \CFile::resizeImageGet( $imageFile, [ 'width' => $avatarSize, 'height' => $avatarSize, ], BX_RESIZE_IMAGE_EXACT, false ); $userData[$userFields["ID"]]['PERSONAL_PHOTO']['SRC'] = $file['src']; } } } } foreach ($logUserData as $logId => $userIdList) { $result[$logId] = []; foreach ($userIdList as $userId) { $result[$logId][] = [ 'ID' => $userId, 'NAME_FORMATTED' => $userData[$userId]['NAME_FORMATTED'], 'PERSONAL_PHOTO' => $userData[$userId]['PERSONAL_PHOTO']['ID'], 'PERSONAL_PHOTO_SRC' => $userData[$userId]['PERSONAL_PHOTO']['SRC'], 'PERSONAL_GENDER' => $userData[$userId]['PERSONAL_GENDER'], 'WEIGHT' => $userWeightData[$userId] ]; } } foreach ($result as $logId => $data) { usort( $data, static function($a, $b) { if ( !isset($a['WEIGHT'], $b['WEIGHT']) || $a['WEIGHT'] === $b['WEIGHT'] ) { return 0; } return ($a['WEIGHT'] > $b['WEIGHT']) ? -1 : 1; } ); $result[$logId] = $data; } return $result; } public static function isCurrentUserExtranet($params = []) { static $result = []; $siteId = (!empty($params['siteId']) ? $params['siteId'] : SITE_ID); if (!isset($result[$siteId])) { $result[$siteId] = ( !\CSocNetUser::isCurrentUserModuleAdmin($siteId, false) && Loader::includeModule('extranet') && !\CExtranet::isIntranetUser() ); } return $result[$siteId]; } public static function userLogSubscribe($params = array()) { static $logAuthorList = array(), $logDestUserList = array(); $userId = (isset($params['userId']) ? (int)$params['userId'] : 0); $logId = (isset($params['logId']) ? (int)$params['logId'] : 0); $typeList = ($params['typeList'] ?? []); $siteId = (isset($params['siteId']) ? (int)$params['siteId'] : SITE_ID); $followByWF = !empty($params['followByWF']); if (!is_array($typeList)) { $typeList = array($typeList); } if ( $userId <= 0 || $logId <= 0 ) { return false; } $followRes = false; if (in_array('FOLLOW', $typeList)) { $followRes = \CSocNetLogFollow::set( $userId, "L".$logId, "Y", ( !empty($params['followDate']) ? ( mb_strtoupper($params['followDate']) === 'CURRENT' ? ConvertTimeStamp(time() + \CTimeZone::getOffset(), "FULL", $siteId) : $params['followDate'] ) : false ), $siteId, $followByWF ); } if (in_array('COUNTER_COMMENT_PUSH', $typeList)) { if (!isset($logAuthorList[$logId])) { $res = LogTable::getList(array( 'filter' => array( '=ID' => $logId ), 'select' => array('USER_ID') )); if ($logFields = $res->fetch()) { $logAuthorList[$logId] = $logFields['USER_ID']; } } if (!isset($logDestUserList[$logId])) { $logDestUserList[$logId] = array(); $res = LogRightTable::getList(array( 'filter' => array( '=LOG_ID' => $logId ), 'select' => array('GROUP_CODE') )); while ($logRightFields = $res->fetch()) { if (preg_match('/^U(\d+)$/', $logRightFields['GROUP_CODE'], $matches)) { $logDestUserList[$logId][] = $matches[1]; } } } if ( $userId != $logAuthorList[$logId] && !in_array($userId, $logDestUserList[$logId]) ) { LogSubscribeTable::set(array( 'userId' => $userId, 'logId' => $logId, 'type' => LogSubscribeTable::TYPE_COUNTER_COMMENT_PUSH, 'ttl' => true )); } } return ( in_array('FOLLOW', $typeList) ? $followRes : true ); } public static function getLFCommentsParams($eventFields = array()): array { $forumMetaData = \CSocNetLogTools::getForumCommentMetaData($eventFields["EVENT_ID"]); if ( $forumMetaData && $eventFields["SOURCE_ID"] > 0 ) { $result = [ "ENTITY_TYPE" => $forumMetaData[1], "ENTITY_XML_ID" => $forumMetaData[0]."_".$eventFields["SOURCE_ID"], "NOTIFY_TAGS" => $forumMetaData[2] ]; // Calendar events could generate different livefeed entries with same SOURCE_ID // That's why we should add entry ID to make comment interface work if ( $eventFields["EVENT_ID"] === 'calendar' && !empty($eventFields["PARAMS"]) && ($calendarEventParams = unserialize(htmlspecialcharsback($eventFields["PARAMS"]), [ 'allowed_classes' => false ])) && !empty($calendarEventParams['COMMENT_XML_ID']) ) { $result["ENTITY_XML_ID"] = $calendarEventParams['COMMENT_XML_ID']; } } elseif ($eventFields["EVENT_ID"] === 'photo') // photo album { $result = array( "ENTITY_TYPE" => 'PA', "ENTITY_XML_ID" => 'PHOTO_ALBUM_'.$eventFields["ID"], "NOTIFY_TAGS" => '' ); } else { $result = array( "ENTITY_TYPE" => mb_substr(mb_strtoupper($eventFields["EVENT_ID"])."_".$eventFields["ID"], 0, 2), "ENTITY_XML_ID" => mb_strtoupper($eventFields["EVENT_ID"])."_".$eventFields["ID"], "NOTIFY_TAGS" => "" ); } if ( mb_strtoupper($eventFields["ENTITY_TYPE"]) === "CRMACTIVITY" && Loader::includeModule('crm') && ($activityFields = \CCrmActivity::getById($eventFields["ENTITY_ID"], false)) && ( $activityFields["TYPE_ID"] == \CCrmActivityType::Task || ( (int)$activityFields['TYPE_ID'] === \CCrmActivityType::Provider && $activityFields['PROVIDER_ID'] === Task::getId() ) ) ) { $result["ENTITY_XML_ID"] = "TASK_".$activityFields["ASSOCIATED_ENTITY_ID"]; } elseif ( $eventFields["ENTITY_TYPE"] === "WF" && is_numeric($eventFields["SOURCE_ID"]) && (int)$eventFields["SOURCE_ID"] > 0 && Loader::includeModule('bizproc') && ($workflowId = \CBPStateService::getWorkflowByIntegerId($eventFields["SOURCE_ID"])) ) { $result["ENTITY_XML_ID"] = "WF_".$workflowId; } return $result; } public static function checkCanCommentInWorkgroup($params) { static $canCommentCached = []; $userId = (isset($params['userId']) ? (int)$params['userId'] : 0); $workgroupId = (isset($params['workgroupId']) ? (int)$params['workgroupId'] : 0); if ( $userId <= 0 || $workgroupId <= 0 ) { return false; } $cacheKey = $userId.'_'.$workgroupId; if (!isset($canCommentCached[$cacheKey])) { $canCommentCached[$cacheKey] = ( \CSocNetFeaturesPerms::canPerformOperation($userId, SONET_ENTITY_GROUP, $workgroupId, "blog", "premoderate_comment") || \CSocNetFeaturesPerms::canPerformOperation($userId, SONET_ENTITY_GROUP, $workgroupId, "blog", "write_comment") ); } return $canCommentCached[$cacheKey]; } public static function checkLivefeedTasksAllowed() { return Option::get('socialnetwork', 'livefeed_allow_tasks', true); } public static function convertSelectorRequestData(array &$postFields = [], array $params = []): void { $perms = (string)($params['perms'] ?? ''); $crm = (bool)($params['crm'] ?? false); $mapping = [ 'DEST_DATA' => 'DEST_CODES', 'GRAT_DEST_DATA' => 'GRAT_DEST_CODES', ]; foreach ($mapping as $from => $to) { if (isset($postFields[$from])) { try { $entities = Json::decode($postFields[$from]); } catch (ArgumentException $e) { $entities = []; } $postFields[$to] = array_merge( ($postFields[$to] ?? []), \Bitrix\Main\UI\EntitySelector\Converter::convertToFinderCodes($entities) ); } } $mapping = [ 'DEST_CODES' => 'SPERM', 'GRAT_DEST_CODES' => 'GRAT', 'EVENT_DEST_CODES' => 'EVENT_PERM' ]; foreach ($mapping as $from => $to) { if (isset($postFields[$from])) { if ( !isset($postFields[$to]) || !is_array($postFields[$to]) ) { $postFields[$to] = []; } foreach ($postFields[$from] as $destCode) { if ($destCode === 'UA') { if (empty($postFields[$to]['UA'])) { $postFields[$to]['UA'] = []; } $postFields[$to]['UA'][] = 'UA'; } elseif (preg_match('/^UE(.+)$/i', $destCode, $matches)) { if (empty($postFields[$to]['UE'])) { $postFields[$to]['UE'] = []; } $postFields[$to]['UE'][] = $matches[1]; } elseif (preg_match('/^U(\d+)$/i', $destCode, $matches)) { if (empty($postFields[$to]['U'])) { $postFields[$to]['U'] = []; } $postFields[$to]['U'][] = 'U' . $matches[1]; } elseif ( $from === 'DEST_CODES' && $perms === BLOG_PERMS_FULL && preg_match('/^UP(\d+)$/i', $destCode, $matches) && Loader::includeModule('blog') ) { if (empty($postFields[$to]['UP'])) { $postFields[$to]['UP'] = []; } $postFields[$to]['UP'][] = 'UP' . $matches[1]; } elseif (preg_match('/^SG(\d+)$/i', $destCode, $matches)) { if (empty($postFields[$to]['SG'])) { $postFields[$to]['SG'] = []; } $postFields[$to]['SG'][] = 'SG' . $matches[1]; } elseif (preg_match('/^DR(\d+)$/i', $destCode, $matches)) { if (empty($postFields[$to]['DR'])) { $postFields[$to]['DR'] = []; } $postFields[$to]['DR'][] = 'DR' . $matches[1]; } elseif ($crm && preg_match('/^CRMCONTACT(\d+)$/i', $destCode, $matches)) { if (empty($postFields[$to]['CRMCONTACT'])) { $postFields[$to]['CRMCONTACT'] = []; } $postFields[$to]['CRMCONTACT'][] = 'CRMCONTACT' . $matches[1]; } elseif ($crm && preg_match('/^CRMCOMPANY(\d+)$/i', $destCode, $matches)) { if (empty($postFields[$to]['CRMCOMPANY'])) { $postFields[$to]['CRMCOMPANY'] = []; } $postFields[$to]['CRMCOMPANY'][] = 'CRMCOMPANY' . $matches[1]; } elseif ($crm && preg_match('/^CRMLEAD(\d+)$/i', $destCode, $matches)) { if (empty($postFields[$to]['CRMLEAD'])) { $postFields[$to]['CRMLEAD'] = []; } $postFields[$to]['CRMLEAD'][] = 'CRMLEAD' . $matches[1]; } elseif ($crm && preg_match('/^CRMDEAL(\d+)$/i', $destCode, $matches)) { if (empty($postFields[$to]['CRMDEAL'])) { $postFields[$to]['CRMDEAL'] = []; } $postFields[$to]['CRMDEAL'][] = 'CRMDEAL' . $matches[1]; } } unset($postFields[$from]); } } } public static function isCurrentPageFirst(array $params = []): bool { $result = false; $componentName = (string)($params['componentName'] ?? ''); $page = (string)($params['page'] ?? ''); $entityId = (int)($params['entityId'] ?? 0); $firstMenuItemCode = (string)($params['firstMenuItemCode'] ?? ''); $canViewTasks = (bool)($params['canView']['tasks'] ?? false); if ($entityId <= 0) { return $result; } if ($componentName === 'bitrix:socialnetwork_group') { if ($firstMenuItemCode !== '') { return ( mb_strpos($page, $firstMenuItemCode) !== false || in_array($page, [ 'group', 'group_general', 'group_tasks' ]) ); } $result = ( ( $page === 'group_tasks' && \CSocNetFeatures::IsActiveFeature(SONET_ENTITY_GROUP, $entityId, 'tasks') && $canViewTasks ) || ( $page === 'group' || $page === 'group_general' ) ); } return $result; } public static function getWorkgroupSliderMenuUrlList(array $componentResult = []): array { return [ 'CARD' => (string)($componentResult['PATH_TO_GROUP_CARD'] ?? ''), 'EDIT' => (string)($componentResult['PATH_TO_GROUP_EDIT'] ?? ''), 'COPY' => (string)($componentResult['PATH_TO_GROUP_COPY'] ?? ''), 'DELETE' => (string)($componentResult['PATH_TO_GROUP_DELETE'] ?? ''), 'LEAVE' => (string)($componentResult['PATH_TO_USER_LEAVE_GROUP'] ?? ''), 'JOIN' => (string)($componentResult['PATH_TO_USER_REQUEST_GROUP'] ?? ''), 'MEMBERS' => (string)($componentResult['PATH_TO_GROUP_USERS'] ?? ''), 'REQUESTS_IN' => (string)($componentResult['PATH_TO_GROUP_REQUESTS'] ?? ''), 'REQUESTS_OUT' => (string)($componentResult['PATH_TO_GROUP_REQUESTS_OUT'] ?? ''), 'FEATURES' => (string)($componentResult['PATH_TO_GROUP_FEATURES'] ?? ''), ]; } public static function listWorkgroupSliderMenuSignedParameters(array $componentParameters = []): array { return array_filter($componentParameters, static function ($key) { /* 'PATH_TO_USER', 'PATH_TO_GROUP_EDIT', 'PATH_TO_GROUP_INVITE', 'PATH_TO_GROUP_CREATE', 'PATH_TO_GROUP_COPY', 'PATH_TO_GROUP_REQUEST_SEARCH', 'PATH_TO_USER_REQUEST_GROUP', 'PATH_TO_GROUP_REQUESTS', 'PATH_TO_GROUP_REQUESTS_OUT', 'PATH_TO_GROUP_MODS', 'PATH_TO_GROUP_USERS', 'PATH_TO_USER_LEAVE_GROUP', 'PATH_TO_GROUP_DELETE', 'PATH_TO_GROUP_FEATURES', 'PATH_TO_GROUP_BAN', 'PATH_TO_SEARCH', 'PATH_TO_SEARCH_TAG', 'PATH_TO_GROUP_BLOG_POST', 'PATH_TO_GROUP_BLOG', 'PATH_TO_BLOG', 'PATH_TO_POST', 'PATH_TO_POST_EDIT', 'PATH_TO_USER_BLOG_POST_IMPORTANT', 'PATH_TO_GROUP_FORUM', 'PATH_TO_GROUP_FORUM_TOPIC', 'PATH_TO_GROUP_FORUM_MESSAGE', 'PATH_TO_GROUP_SUBSCRIBE', 'PATH_TO_MESSAGE_TO_GROUP', 'PATH_TO_GROUP_TASKS', 'PATH_TO_GROUP_TASKS_TASK', 'PATH_TO_GROUP_TASKS_VIEW', 'PATH_TO_GROUP_CONTENT_SEARCH', 'PATH_TO_MESSAGES_CHAT', 'PATH_TO_VIDEO_CALL', 'PATH_TO_CONPANY_DEPARTMENT', 'PATH_TO_USER_LOG', 'PATH_TO_GROUP_LOG', 'PAGE_VAR', 'USER_VAR', 'GROUP_VAR', 'TASK_VAR', 'TASK_ACTION_VAR', 'SET_NAV_CHAIN', 'USER_ID', 'GROUP_ID', 'ITEMS_COUNT', 'FORUM_ID', 'BLOG_GROUP_ID', 'TASK_FORUM_ID', 'THUMBNAIL_LIST_SIZE', 'DATE_TIME_FORMAT', 'SHOW_YEAR', 'NAME_TEMPLATE', 'SHOW_LOGIN', 'CAN_OWNER_EDIT_DESKTOP', 'CACHE_TYPE', 'CACHE_TIME', 'USE_MAIN_MENU', 'LOG_SUBSCRIBE_ONLY', 'GROUP_PROPERTY', 'GROUP_USE_BAN', 'BLOG_ALLOW_POST_CODE', 'SHOW_RATING', 'LOG_THUMBNAIL_SIZE', 'LOG_COMMENT_THUMBNAIL_SIZE', 'LOG_NEW_TEMPLATE', */ return (in_array($key, [ 'GROUP_ID', 'SET_TITLE', 'PATH_TO_GROUP', ])); }, ARRAY_FILTER_USE_KEY); } public static function getWorkgroupSliderMenuSignedParameters(array $params): string { return Main\Component\ParameterSigner::signParameters(self::getWorkgroupSliderMenuSignedParametersSalt(), $params); } public static function getWorkgroupSliderMenuUnsignedParameters(array $sourceParametersList = []) { foreach ($sourceParametersList as $source) { if (isset($source['signedParameters']) && is_string($source['signedParameters'])) { try { $componentParameters = ParameterSigner::unsignParameters( self::getWorkgroupSliderMenuSignedParametersSalt(), $source['signedParameters'] ); $componentParameters['IFRAME'] = 'Y'; return $componentParameters; } catch (BadSignatureException $exception) {} return []; } } return []; } public static function getWorkgroupSliderMenuSignedParametersSalt(): string { return 'bitrix:socialnetwork.group.card.menu'; } public static function getWorkgroupAvatarToken($fileId = 0): string { if ($fileId <= 0) { return ''; } $filePath = \CFile::getPath($fileId); if ((string)$filePath === '') { return ''; } $signer = new \Bitrix\Main\Security\Sign\Signer; return $signer->sign(serialize([ $fileId, $filePath ]), 'workgroup_avatar_token'); } public static function checkEmptyParamInteger(&$params, $paramName, $defaultValue): void { $params[$paramName] = (isset($params[$paramName]) && (int)$params[$paramName] > 0 ? (int)$params[$paramName] : $defaultValue); } public static function checkEmptyParamString(&$params, $paramName, $defaultValue): void { $params[$paramName] = (isset($params[$paramName]) && trim($params[$paramName]) !== '' ? trim($params[$paramName]) : $defaultValue); } public static function checkTooltipComponentParams($params): array { if (ModuleManager::isModuleInstalled('intranet')) { $defaultFields = [ 'EMAIL', 'PERSONAL_MOBILE', 'WORK_PHONE', 'PERSONAL_ICQ', 'PERSONAL_PHOTO', 'PERSONAL_CITY', 'WORK_COMPANY', 'WORK_POSITION', ]; $defaultProperties = [ 'UF_DEPARTMENT', 'UF_PHONE_INNER', ]; } else { $defaultFields = [ "PERSONAL_ICQ", "PERSONAL_BIRTHDAY", "PERSONAL_PHOTO", "PERSONAL_CITY", "WORK_COMPANY", "WORK_POSITION" ]; $defaultProperties = []; } return [ 'SHOW_FIELDS_TOOLTIP' => ($params['SHOW_FIELDS_TOOLTIP'] ?? unserialize(Option::get('socialnetwork', 'tooltip_fields', serialize($defaultFields)), ['allowed_classes' => false])), 'USER_PROPERTY_TOOLTIP' => ($params['USER_PROPERTY_TOOLTIP'] ?? unserialize(Option::get('socialnetwork', 'tooltip_properties', serialize($defaultProperties)), ['allowed_classes' => false])), ]; } public static function getWorkgroupPageTitle(array $params = []): string { $workgroupName = (string)($params['WORKGROUP_NAME'] ?? ''); $workgroupId = (int)($params['WORKGROUP_ID'] ?? 0); if ( $workgroupName === '' && $workgroupId > 0 ) { $groupFields = \CSocNetGroup::getById($workgroupId, true); if (!empty($groupFields)) { $workgroupName = $groupFields['NAME']; } } return Loc::getMessage('SONET_HELPER_PAGE_TITLE_WORKGROUP_TEMPLATE', [ '#WORKGROUP#' => $workgroupName, '#TITLE#' => ($params['TITLE'] ?? ''), ]); } }