PageRenderTime 36ms CodeModel.GetById 1ms RepoModel.GetById 0ms app.codeStats 0ms

/modules/socialnetwork/classes/general/rest.php

https://gitlab.com/alexprowars/bitrix
PHP | 2049 lines | 1945 code | 103 blank | 1 comment | 82 complexity | b478c74250c9968639214edf7adc969f MD5 | raw file
  1. <?php
  2. use Bitrix\Disk\File;
  3. use Bitrix\Intranet\Integration\Templates\Bitrix24\ThemePicker;
  4. use Bitrix\Main\Text\Emoji;
  5. use Bitrix\Socialnetwork\ComponentHelper;
  6. use Bitrix\Main\Config\Option;
  7. use Bitrix\Main\Loader;
  8. use Bitrix\Rest\RestException;
  9. use Bitrix\Main\ModuleManager;
  10. use Bitrix\Socialnetwork\Helper\Workgroup;
  11. use Bitrix\Socialnetwork\Item\Helper;
  12. use Bitrix\Socialnetwork\UserToGroupTable;
  13. if (!Loader::includeModule('rest'))
  14. {
  15. return;
  16. }
  17. class CSocNetLogRestService extends IRestService
  18. {
  19. public const PERM_DENY = 'D';
  20. public const PERM_READ = 'R';
  21. public const PERM_WRITE = 'W';
  22. private static $arAllowedOperations = array('', '!', '<', '<=', '>', '>=', '><', '!><', '?', '=', '!=', '%', '!%', '');
  23. public static function OnRestServiceBuildDescription(): array
  24. {
  25. return array(
  26. "log" => array(
  27. "log.blogpost.get" => array("CSocNetLogRestService", "getBlogPost"),
  28. 'log.blogpost.user.get' => array('callback' => array(__CLASS__, 'getUserBlogPost'), 'options' => array('private' => true)),
  29. "log.blogpost.add" => array("CSocNetLogRestService", "addBlogPost"),
  30. "log.blogpost.update" => array("CSocNetLogRestService", "updateBlogPost"),
  31. "log.blogpost.share" => array("CSocNetLogRestService", "shareBlogPost"),
  32. "log.blogpost.delete" => array("CSocNetLogRestService", "deleteBlogPost"),
  33. "log.blogpost.getusers.important" => array("CSocNetLogRestService", "getBlogPostUsersImprtnt"),
  34. "log.blogcomment.add" => array("CSocNetLogRestService", "addBlogComment"),
  35. 'log.blogcomment.user.get' => array('callback' => array(__CLASS__, 'getUserBlogComment'), 'options' => array('private' => true)),
  36. "log.blogcomment.delete" => array("CSocNetLogRestService", "deleteBlogComment"),
  37. 'log.comment.user.get' => array('callback' => array(__CLASS__, 'getUserLogComment'), 'options' => array('private' => true)),
  38. "log.comment.delete" => array("CSocNetLogRestService", "deleteLogComment"),
  39. CRestUtil::EVENTS => array(
  40. 'onLivefeedPostAdd' => self::createEventInfo('socialnetwork', 'OnAfterSocNetLogAdd', array(CSocNetLogBlogPostRestProxy::class, 'processEvent')),
  41. 'onLivefeedPostUpdate' => self::createEventInfo('socialnetwork', 'OnAfterSocNetLogUpdate', array(CSocNetLogBlogPostRestProxy::class, 'processEvent')),
  42. 'onLivefeedPostDelete' => self::createEventInfo('socialnetwork', 'OnSocNetLogDelete', array(CSocNetLogBlogPostRestProxy::class, 'processEvent')),
  43. ),
  44. ),
  45. "sonet_group" => array(
  46. "sonet_group.get" => array("CSocNetLogRestService", "getGroup"),
  47. "sonet_group.create" => array("CSocNetLogRestService", "createGroup"),
  48. "sonet_group.update" => array("CSocNetLogRestService", "updateGroup"),
  49. "sonet_group.delete" => array("CSocNetLogRestService", "deleteGroup"),
  50. "sonet_group.setowner" => array("CSocNetLogRestService", "setGroupOwner"),
  51. "sonet_group.user.get" => array("CSocNetLogRestService", "getGroupUsers"),
  52. "sonet_group.user.invite" => array("CSocNetLogRestService", "inviteGroupUsers"),
  53. "sonet_group.user.request" => array("CSocNetLogRestService", "requestGroupUser"),
  54. "sonet_group.user.add" => array("CSocNetLogRestService", "addGroupUsers"),
  55. "sonet_group.user.update" => array("CSocNetLogRestService", "updateGroupUsers"),
  56. "sonet_group.user.delete" => array("CSocNetLogRestService", "deleteGroupUsers"),
  57. "sonet_group.user.groups" => array("CSocNetLogRestService", "getUserGroups"),
  58. "sonet_group.feature.access" => array("CSocNetLogRestService", "getGroupFeatureAccess"),
  59. "sonet_group_subject.get" => array("CSocNetLogRestService", "getGroupSubject"),
  60. "sonet_group_subject.add" => array("CSocNetLogRestService", "addGroupSubject"),
  61. "sonet_group_subject.update" => array("CSocNetLogRestService", "updateGroupSubject"),
  62. "sonet_group_subject.delete" => array("CSocNetLogRestService", "deleteGroupSubject"),
  63. CRestUtil::EVENTS => array(
  64. 'onSonetGroupAdd' => self::createEventInfo('socialnetwork', 'OnSocNetGroupAdd', array(CSocNetGroupRestProxy::class, 'processEvent')),
  65. 'onSonetGroupUpdate' => self::createEventInfo('socialnetwork', 'OnSocNetGroupUpdate', array(CSocNetGroupRestProxy::class, 'processEvent')),
  66. 'onSonetGroupDelete' => self::createEventInfo('socialnetwork', 'OnSocNetGroupDelete', array(CSocNetGroupRestProxy::class, 'processEvent')),
  67. 'onSonetGroupSubjectAdd' => self::createEventInfo('socialnetwork', 'OnSocNetGroupSubjectAdd', array(CSocNetGroupSubjectRestProxy::class, 'processEvent')),
  68. 'onSonetGroupSubjectUpdate' => self::createEventInfo('socialnetwork', 'OnSocNetGroupSubjectUpdate', array(CSocNetGroupSubjectRestProxy::class, 'processEvent')),
  69. 'onSonetGroupSubjectDelete' => self::createEventInfo('socialnetwork', 'OnSocNetGroupSubjectDelete', array(CSocNetGroupSubjectRestProxy::class, 'processEvent'))
  70. ),
  71. CRestUtil::PLACEMENTS => array(
  72. 'SONET_GROUP_DETAIL_TAB' => array()
  73. ),
  74. )
  75. );
  76. }
  77. public static function createEventInfo($moduleName, $eventName, array $callback): array
  78. {
  79. return array($moduleName, $eventName, $callback, array('category' => \Bitrix\Rest\Sqs::CATEGORY_DEFAULT));
  80. }
  81. private static function getBlogPostEventId(): array
  82. {
  83. static $blogPostEventIdList = null;
  84. if ($blogPostEventIdList === null)
  85. {
  86. $blogPostLivefeedProvider = new \Bitrix\Socialnetwork\Livefeed\BlogPost;
  87. $blogPostEventIdList = $blogPostLivefeedProvider->getEventId();
  88. }
  89. $arEventId = $blogPostEventIdList;
  90. $arEventIdFullset = array();
  91. foreach ($arEventId as $eventId)
  92. {
  93. $arEventIdFullset = array_merge($arEventIdFullset, CSocNetLogTools::FindFullSetByEventID($eventId));
  94. }
  95. return array_unique($arEventIdFullset);
  96. }
  97. private static function getBlogCommentEventId(): ?array
  98. {
  99. static $blogCommentEventIdList = null;
  100. if ($blogCommentEventIdList === null)
  101. {
  102. $blogCommentLivefeedProvider = new \Bitrix\Socialnetwork\Livefeed\BlogComment;
  103. $blogCommentEventIdList = $blogCommentLivefeedProvider->getEventId();
  104. }
  105. return $blogCommentEventIdList;
  106. }
  107. private static function getLogCommentEventId(): ?array
  108. {
  109. static $logCommentEventIdList = null;
  110. if ($logCommentEventIdList === null)
  111. {
  112. $logCommentLivefeedProvider = new \Bitrix\Socialnetwork\Livefeed\LogComment;
  113. $logCommentEventIdList = $logCommentLivefeedProvider->getEventId();
  114. }
  115. return $logCommentEventIdList;
  116. }
  117. public static function getBlogPost($fields, $n, $server): array
  118. {
  119. global $USER_FIELD_MANAGER;
  120. $result = array();
  121. if (!CModule::IncludeModule("blog"))
  122. {
  123. return $result;
  124. }
  125. $tzOffset = CTimeZone::getOffset();
  126. $arOrder = [ 'LOG_UPDATE' => 'DESC' ];
  127. $res = CUser::getById(self::getCurrentUserId());
  128. if ($userFields = $res->Fetch())
  129. {
  130. $currentUserIntranet = (
  131. !empty($userFields["UF_DEPARTMENT"])
  132. && is_array($userFields["UF_DEPARTMENT"])
  133. && (int)$userFields["UF_DEPARTMENT"][0] > 0
  134. );
  135. $extranetSiteId = self::getExtranetSiteId();
  136. if (
  137. empty($extranetSiteId)
  138. || $currentUserIntranet
  139. )
  140. {
  141. $userSiteFields = CSocNetLogComponent::getSiteByDepartmentId($userFields["UF_DEPARTMENT"]);
  142. if (!empty($userSiteFields))
  143. {
  144. $siteId = $userSiteFields['LID'];
  145. }
  146. }
  147. elseif (
  148. !empty($extranetSiteId)
  149. && !$currentUserIntranet
  150. )
  151. {
  152. $siteId = $extranetSiteId;
  153. }
  154. else
  155. {
  156. $siteId = CSite::getDefSite();
  157. }
  158. }
  159. $filter = [
  160. "EVENT_ID" => self::getBlogPostEventId(),
  161. "SITE_ID" => [ $siteId, false ],
  162. "<=LOG_DATE" => "NOW"
  163. ];
  164. if (
  165. isset($fields['POST_ID'])
  166. && (int)$fields['POST_ID'] > 0
  167. )
  168. {
  169. $filter['SOURCE_ID'] = $fields['POST_ID'];
  170. }
  171. elseif (
  172. isset($fields['LOG_RIGHTS'])
  173. && is_array($fields['LOG_RIGHTS'])
  174. )
  175. {
  176. $filter["LOG_RIGHTS"] = $fields['LOG_RIGHTS'];
  177. }
  178. $arListParams = array(
  179. "CHECK_RIGHTS" => "Y",
  180. "USE_FOLLOW" => "N",
  181. "USE_SUBSCRIBE" => "N"
  182. );
  183. $dbLog = CSocNetLog::GetList(
  184. $arOrder,
  185. $filter,
  186. false,
  187. self::getNavData($n),
  188. array("ID", "SOURCE_ID"),
  189. $arListParams
  190. );
  191. $arPostId = $arPostIdToGet = array();
  192. while ($arLog = $dbLog->Fetch())
  193. {
  194. $arPostId[] = $arLog["SOURCE_ID"];
  195. }
  196. $cacheTtl = 2592000;
  197. foreach ($arPostId as $key => $postId)
  198. {
  199. $cacheId = 'blog_post_socnet_rest_'.$postId.'_ru'.($tzOffset <> 0 ? '_'.$tzOffset : '');
  200. $cacheDir = ComponentHelper::getBlogPostCacheDir(array(
  201. 'TYPE' => 'post',
  202. 'POST_ID' => $postId
  203. ));
  204. $obCache = new CPHPCache;
  205. if ($obCache->InitCache($cacheTtl, $cacheId, $cacheDir))
  206. {
  207. $result[$key] = $obCache->GetVars();
  208. }
  209. else
  210. {
  211. $arPostIdToGet[$key] = $postId;
  212. }
  213. $obCache->EndDataCache();
  214. }
  215. if (!empty($arPostIdToGet))
  216. {
  217. foreach ($arPostIdToGet as $key => $postId)
  218. {
  219. $cacheId = 'blog_post_socnet_rest_'.$postId.'_ru'.($tzOffset <> 0 ? '_'.$tzOffset : '');
  220. $cacheDir = ComponentHelper::getBlogPostCacheDir(array(
  221. 'TYPE' => 'post_general',
  222. 'POST_ID' => $postId
  223. ));
  224. $obCache = new CPHPCache;
  225. $obCache->InitCache($cacheTtl, $cacheId, $cacheDir);
  226. $obCache->StartDataCache();
  227. $dbPost = CBlogPost::GetList(
  228. array(),
  229. array("ID" => $postId),
  230. false,
  231. false,
  232. array(
  233. "ID",
  234. "BLOG_ID",
  235. "PUBLISH_STATUS",
  236. "TITLE",
  237. "AUTHOR_ID",
  238. "ENABLE_COMMENTS",
  239. "NUM_COMMENTS",
  240. "CODE",
  241. "MICRO",
  242. "DETAIL_TEXT",
  243. "DATE_PUBLISH",
  244. "CATEGORY_ID",
  245. "HAS_SOCNET_ALL",
  246. "HAS_TAGS",
  247. "HAS_IMAGES",
  248. "HAS_PROPS",
  249. "HAS_COMMENT_IMAGES"
  250. )
  251. );
  252. if ($arPost = $dbPost->Fetch())
  253. {
  254. if (!empty($arPost['DETAIL_TEXT']))
  255. {
  256. $arPost['DETAIL_TEXT'] = Emoji::decode($arPost['DETAIL_TEXT']);
  257. }
  258. if ($arPost["PUBLISH_STATUS"] !== BLOG_PUBLISH_STATUS_PUBLISH)
  259. {
  260. unset($arPost);
  261. }
  262. else
  263. {
  264. if (!empty($arPost['DATE_PUBLISH']))
  265. {
  266. $arPost['DATE_PUBLISH'] = CRestUtil::convertDateTime($arPost['DATE_PUBLISH']);
  267. }
  268. if ($arPost["HAS_PROPS"] !== 'N')
  269. {
  270. $arPostFields = $USER_FIELD_MANAGER->GetUserFields("BLOG_POST", $arPost["ID"], LANGUAGE_ID);
  271. $arPost = array_merge($arPost, $arPostFields);
  272. }
  273. if (
  274. !empty($arPost['UF_BLOG_POST_FILE'])
  275. && !empty($arPost['UF_BLOG_POST_FILE']['VALUE'])
  276. )
  277. {
  278. $arPost['FILES'] = $arPost['UF_BLOG_POST_FILE']['VALUE'];
  279. }
  280. $result[$key] = $arPost;
  281. }
  282. }
  283. $obCache->EndDataCache($arPost);
  284. }
  285. }
  286. ksort($result);
  287. return self::setNavData($result, $dbLog);
  288. }
  289. public static function getUserBlogPost($arParams, $offset, CRestServer $server): array
  290. {
  291. $arParams = array_change_key_case($arParams, CASE_UPPER);
  292. $result = Array(
  293. 'POSTS' => array(),
  294. 'FILES' => array(),
  295. );
  296. if (!Loader::includeModule("blog"))
  297. {
  298. return $result;
  299. }
  300. $userId = (int)(
  301. isset($arParams["USER_ID"])
  302. && (int)$arParams["USER_ID"] > 0
  303. && self::isAdmin()
  304. ? $arParams["USER_ID"]
  305. : self::getCurrentUserId()
  306. );
  307. $otherUserMode = ($userId !== self::getCurrentUserId());
  308. if ($userId <= 0)
  309. {
  310. throw new Bitrix\Rest\RestException("User ID can't be empty", "ID_EMPTY", CRestServer::STATUS_WRONG_REQUEST);
  311. }
  312. if (isset($arParams['FIRST_ID']))
  313. {
  314. $options['FIRST_ID'] = (int)$arParams['FIRST_ID'];
  315. }
  316. else
  317. {
  318. $options['LAST_ID'] = isset($arParams['LAST_ID']) && (int)$arParams['LAST_ID'] > 0 ? (int)$arParams['LAST_ID'] : 0;
  319. }
  320. $options['LIMIT'] = isset($arParams['LIMIT'])? ((int)$arParams['LIMIT'] > 1000 ? 1000 : (int)$arParams['LIMIT']) : 100;
  321. $filter = [
  322. '=USER_ID' => $userId,
  323. '@EVENT_ID' => self::getBlogPostEventId()
  324. ];
  325. if (isset($options['FIRST_ID']))
  326. {
  327. $order = [];
  328. if ((int)$options['FIRST_ID'] > 0)
  329. {
  330. $filter['>ID'] = $options['FIRST_ID'];
  331. }
  332. }
  333. else
  334. {
  335. $order = [ 'ID' => 'DESC' ];
  336. if (isset($options['LAST_ID']) && (int)$options['LAST_ID'] > 0)
  337. {
  338. $filter['<ID'] = (int)$options['LAST_ID'];
  339. }
  340. }
  341. $logIdList = array();
  342. $res = Bitrix\Socialnetwork\LogTable::getList(array(
  343. 'filter' => $filter,
  344. 'select' => array(
  345. 'ID', 'SOURCE_ID'
  346. ),
  347. 'order' => $order,
  348. 'limit' => $options['LIMIT']
  349. ));
  350. $postIdList = array();
  351. while ($logFields = $res->fetch())
  352. {
  353. if ((int)$logFields['SOURCE_ID'] > 0)
  354. {
  355. $postIdList[] = $logFields['SOURCE_ID'];
  356. $logIdList[$logFields['SOURCE_ID']] = $logFields['ID'];
  357. }
  358. }
  359. $postIdList = array_unique($postIdList);
  360. if (empty($postIdList))
  361. {
  362. return $result;
  363. }
  364. $res = Bitrix\Blog\PostTable::getList([
  365. 'filter' => [
  366. '@ID' => $postIdList,
  367. ],
  368. 'select' => [
  369. 'ID', 'DATE_CREATE', 'TITLE', 'DETAIL_TEXT', 'UF_BLOG_POST_FILE'
  370. ],
  371. 'order' => [ 'ID' => 'DESC' ],
  372. ]);
  373. $attachedIdList = [];
  374. $postAttachedList = [];
  375. while ($postFields = $res->fetch())
  376. {
  377. $result['POSTS'][$postFields['ID']] = [
  378. 'ID' => (int)$logIdList[$postFields['ID']],
  379. 'POST_ID' => (int)$postFields['ID'],
  380. 'DATE_CREATE' => $postFields['DATE_CREATE'],
  381. 'TITLE' => ($otherUserMode ? '' : (string)$postFields['TITLE']),
  382. 'TEXT' => ($otherUserMode ? '' : (string)$postFields['DETAIL_TEXT']),
  383. 'ATTACH' => [],
  384. ];
  385. if (!empty($postFields['UF_BLOG_POST_FILE']))
  386. {
  387. if (is_array($postFields['UF_BLOG_POST_FILE']))
  388. {
  389. $attached = $postFields['UF_BLOG_POST_FILE'];
  390. }
  391. elseif ((int)$postFields['UF_BLOG_POST_FILE'] > 0)
  392. {
  393. $attached = array((int)$postFields['UF_BLOG_POST_FILE']);
  394. }
  395. else
  396. {
  397. $attached = array();
  398. }
  399. if (!empty($attached))
  400. {
  401. $attachedIdList = array_merge($attachedIdList, $attached);
  402. }
  403. $postAttachedList[$postFields['ID']] = $attached;
  404. }
  405. }
  406. $attachedObjectList = [];
  407. if (
  408. !empty($attachedIdList)
  409. && Loader::includeModule('disk')
  410. )
  411. {
  412. $res = Bitrix\Disk\AttachedObject::getList([
  413. 'filter' => [
  414. '@ID' => array_unique($attachedIdList)
  415. ],
  416. 'select' => [ 'ID', 'OBJECT_ID' ],
  417. ]);
  418. while ($attachedObjectFields = $res->fetch())
  419. {
  420. $diskObjectId = $attachedObjectFields['OBJECT_ID'];
  421. if ($fileData = self::getFileData($diskObjectId))
  422. {
  423. $attachedObjectList[$attachedObjectFields['ID']] = $diskObjectId;
  424. $result['FILES'][$diskObjectId] = $fileData;
  425. }
  426. }
  427. }
  428. foreach ($result['POSTS'] as $key => $value)
  429. {
  430. if ($value['DATE_CREATE'] instanceof \Bitrix\Main\Type\DateTime)
  431. {
  432. $result['POSTS'][$key]['DATE_CREATE'] = date('c', $value['DATE_CREATE']->getTimestamp());
  433. }
  434. if (!empty($postAttachedList[$key]))
  435. {
  436. foreach ($postAttachedList[$key] as $attachedId)
  437. {
  438. if (!empty($attachedObjectList[$attachedId]))
  439. {
  440. $result['POSTS'][$key]['ATTACH'][] = $attachedObjectList[$attachedId];
  441. }
  442. }
  443. }
  444. $result['POSTS'][$key] = array_change_key_case($result['POSTS'][$key], CASE_LOWER);
  445. }
  446. $result['POSTS'] = array_values($result['POSTS']);
  447. $result['FILES'] = self::convertFileData($result['FILES']);
  448. return $result;
  449. }
  450. public static function addBlogPost($arFields)
  451. {
  452. global $APPLICATION;
  453. try
  454. {
  455. $postId = Helper::addBlogPost($arFields, \Bitrix\Main\Engine\Controller::SCOPE_REST);
  456. if ($postId <= 0)
  457. {
  458. $e = $APPLICATION->getException();
  459. throw new Exception($e ? $e->getString() : 'Cannot add blog post');
  460. }
  461. }
  462. catch (Exception $e)
  463. {
  464. throw new Exception($e->getMessage(), $e->getCode());
  465. }
  466. return $postId;
  467. }
  468. public static function updateBlogPost($arFields)
  469. {
  470. global $APPLICATION;
  471. try
  472. {
  473. $postId = Helper::updateBlogPost($arFields, \Bitrix\Main\Engine\Controller::SCOPE_REST);
  474. if ($postId <= 0)
  475. {
  476. $e = $APPLICATION->getException();
  477. throw new Exception($e ? $e->getString() : 'Cannot update blog post');
  478. }
  479. }
  480. catch (Exception $e)
  481. {
  482. throw new Exception($e->getMessage(), $e->getCode());
  483. }
  484. return $postId;
  485. }
  486. public static function deleteBlogPost($arFields): bool
  487. {
  488. try
  489. {
  490. $result = Helper::deleteBlogPost([
  491. 'POST_ID' => (int)$arFields['POST_ID'],
  492. ]);
  493. }
  494. catch (Exception $e)
  495. {
  496. throw new Exception($e->getMessage(), $e->getCode());
  497. }
  498. return $result;
  499. }
  500. public static function shareBlogPost($fields): bool
  501. {
  502. $postId = (int)$fields['POST_ID'];
  503. if ($postId <= 0)
  504. {
  505. throw new Exception('Wrong post ID');
  506. }
  507. if (!Loader::includeModule('blog'))
  508. {
  509. throw new Exception('Blog module not installed');
  510. }
  511. $siteId = (
  512. is_set($fields, "SITE_ID")
  513. && !empty($fields["SITE_ID"])
  514. ? $fields["SITE_ID"]
  515. : SITE_ID
  516. );
  517. $blogId = false;
  518. if (
  519. !is_set($fields, "BLOG_ID")
  520. || (int)$fields["BLOG_ID"] <= 0
  521. )
  522. {
  523. $res = \Bitrix\Blog\PostTable::getList(array(
  524. 'filter' => array(
  525. '=ID' => $postId
  526. ),
  527. 'select' => array('BLOG_ID')
  528. ));
  529. if (
  530. ($postFields = $res->fetch())
  531. && !empty($postFields['BLOG_ID'])
  532. )
  533. {
  534. $blogId = (int)$postFields['BLOG_ID'];
  535. }
  536. }
  537. else
  538. {
  539. $blogId = (int)$fields["BLOG_ID"];
  540. }
  541. $blogPostPermsNewList = $fields['DEST'];
  542. if (!is_array($blogPostPermsNewList))
  543. {
  544. $blogPostPermsNewList = array($blogPostPermsNewList);
  545. }
  546. foreach ($blogPostPermsNewList as $key => $code)
  547. {
  548. if (
  549. $code !== 'UA'
  550. && !preg_match('/^SG(\d+)$/', $code, $matches)
  551. && !preg_match('/^U(\d+)$/', $code, $matches)
  552. && !preg_match('/^UE(.+)$/', $code, $matches)
  553. && !preg_match('/^DR(\d+)$/', $code, $matches)
  554. )
  555. {
  556. unset($blogPostPermsNewList[$key]);
  557. }
  558. }
  559. if (empty($blogPostPermsNewList))
  560. {
  561. throw new Exception('Wrong destinations');
  562. }
  563. $currentUserId = (
  564. isset($fields["USER_ID"])
  565. && (int)$fields["USER_ID"] > 0
  566. && self::isAdmin()
  567. ? $fields["USER_ID"]
  568. : self::getCurrentUserId()
  569. );
  570. $currentUserPerm = self::getBlogPostPerm(array(
  571. 'USER_ID' => $currentUserId,
  572. 'POST_ID' => $postId
  573. ));
  574. if ($currentUserPerm <= \Bitrix\Blog\Item\Permissions::READ)
  575. {
  576. throw new Exception('No read perms');
  577. }
  578. $resultFields = array(
  579. 'ERROR_MESSAGE' => false,
  580. 'PUBLISH_STATUS' => BLOG_PUBLISH_STATUS_PUBLISH
  581. );
  582. if (ModuleManager::isModuleInstalled('mail')
  583. && ModuleManager::isModuleInstalled('intranet')
  584. && (
  585. !Loader::includeModule('bitrix24')
  586. || CBitrix24::isEmailConfirmed()
  587. )
  588. )
  589. {
  590. $destinationList = $blogPostPermsNewList;
  591. ComponentHelper::processBlogPostNewMailUserDestinations($destinationList);
  592. $blogPostPermsNewList = array_unique($destinationList);
  593. }
  594. $permsNew = ComponentHelper::checkBlogPostDestinationList(array(
  595. 'DEST' => $blogPostPermsNewList,
  596. 'SITE_ID' => $siteId,
  597. 'AUTHOR_ID' => $currentUserId,
  598. ), $resultFields);
  599. if ($resultFields['ERROR_MESSAGE'])
  600. {
  601. throw new Exception($resultFields['ERROR_MESSAGE']);
  602. }
  603. elseif ($resultFields['PUBLISH_STATUS'] !== BLOG_PUBLISH_STATUS_PUBLISH)
  604. {
  605. throw new Exception('No permissions to share by this user (ID =' . $currentUserId . ')');
  606. }
  607. $permsFull = array();
  608. $blogPostPermsOldList = CBlogPost::getSocNetPerms($postId);
  609. foreach ($blogPostPermsOldList as $type => $val)
  610. {
  611. foreach ($val as $id => $values)
  612. {
  613. if ($type !== 'U')
  614. {
  615. $permsFull[] = $type.$id;
  616. }
  617. else
  618. {
  619. $permsFull[] = (
  620. in_array('US' . $id, $values, true)
  621. ? 'UA'
  622. : $type . $id
  623. );
  624. }
  625. }
  626. }
  627. foreach ($permsNew as $key => $code)
  628. {
  629. if (!in_array($code, $permsFull))
  630. {
  631. $permsFull[] = $code;
  632. }
  633. else
  634. {
  635. unset($permsNew[$key]);
  636. }
  637. }
  638. if (!empty($permsNew))
  639. {
  640. ComponentHelper::processBlogPostShare(
  641. array(
  642. "POST_ID" => $postId,
  643. "BLOG_ID" => $blogId,
  644. "SITE_ID" => $siteId,
  645. "SONET_RIGHTS" => $permsFull,
  646. "NEW_RIGHTS" => $permsNew,
  647. "USER_ID" => $currentUserId
  648. ),
  649. array(
  650. 'PATH_TO_POST' => \Bitrix\Socialnetwork\Helper\Path::get('userblogpost_page', $siteId)
  651. )
  652. );
  653. }
  654. return true;
  655. }
  656. public static function getBlogPostUsersImprtnt($fields): array
  657. {
  658. global $CACHE_MANAGER;
  659. if (!is_array($fields))
  660. {
  661. throw new Exception('Incorrect input data');
  662. }
  663. $arParams["postId"] = (int)$fields['POST_ID'];
  664. if ($arParams['postId'] <= 0)
  665. {
  666. throw new Exception('Wrong post ID');
  667. }
  668. $arParams["nTopCount"] = 500;
  669. $arParams["paramName"] = 'BLOG_POST_IMPRTNT';
  670. $arParams["paramValue"] = 'Y';
  671. $result = array();
  672. $cache = new CPHPCache();
  673. $cache_id = "blog_post_param_".serialize(array(
  674. $arParams["postId"],
  675. $arParams["nTopCount"],
  676. $arParams["paramName"],
  677. $arParams["paramValue"]
  678. ));
  679. $cache_path = $CACHE_MANAGER->GetCompCachePath(CComponentEngine::MakeComponentPath("socialnetwork.blog.blog"))."/".$arParams["postId"];
  680. $cache_time = (defined("BX_COMP_MANAGED_CACHE") ? 3600*24*365 : 600);
  681. if ($cache->InitCache($cache_time, $cache_id, $cache_path))
  682. {
  683. $result = $cache->GetVars();
  684. }
  685. else
  686. {
  687. $cache->StartDataCache($cache_time, $cache_id, $cache_path);
  688. if (CModule::IncludeModule("blog"))
  689. {
  690. if (defined("BX_COMP_MANAGED_CACHE"))
  691. {
  692. $CACHE_MANAGER->StartTagCache($cache_path);
  693. $CACHE_MANAGER->RegisterTag($arParams["paramName"].$arParams["postId"]);
  694. }
  695. if ($arBlogPost = CBlogPost::GetByID($arParams["postId"]))
  696. {
  697. $postPerms = CBlogPost::GetSocNetPostPerms($arParams["postId"], true, self::getCurrentUserId(), $arBlogPost["AUTHOR_ID"]);
  698. if ($postPerms >= BLOG_PERMS_READ)
  699. {
  700. $res = CBlogUserOptions::GetList(
  701. [],
  702. [
  703. 'POST_ID' => $arParams["postId"],
  704. 'NAME' => $arParams["paramName"],
  705. 'VALUE' => $arParams["paramValue"],
  706. 'USER_ACTIVE' => 'Y',
  707. ],
  708. [
  709. "nTopCount" => $arParams["nTopCount"],
  710. 'SELECT' => [ 'USER_ID' ],
  711. ]
  712. );
  713. if ($res)
  714. {
  715. while ($userOptionFields = $res->fetch())
  716. {
  717. $result[] = $userOptionFields['USER_ID'];
  718. }
  719. }
  720. }
  721. }
  722. if (defined("BX_COMP_MANAGED_CACHE"))
  723. {
  724. $CACHE_MANAGER->EndTagCache();
  725. }
  726. $cache->EndDataCache($result);
  727. }
  728. }
  729. return $result;
  730. }
  731. public static function getUserBlogComment($arParams, $offset, CRestServer $server): array
  732. {
  733. $arParams = array_change_key_case($arParams, CASE_UPPER);
  734. $result = Array(
  735. 'COMMENTS' => array(),
  736. 'FILES' => array(),
  737. );
  738. if (!Loader::includeModule("blog"))
  739. {
  740. return $result;
  741. }
  742. $userId = (int)(
  743. isset($arParams["USER_ID"])
  744. && (int)$arParams['USER_ID'] > 0
  745. && self::isAdmin()
  746. ? $arParams["USER_ID"]
  747. : self::getCurrentUserId()
  748. );
  749. $otherUserMode = ($userId !== self::getCurrentUserId());
  750. if ($userId <= 0)
  751. {
  752. throw new Bitrix\Rest\RestException("User ID can't be empty", "ID_EMPTY", CRestServer::STATUS_WRONG_REQUEST);
  753. }
  754. if (isset($arParams['FIRST_ID']))
  755. {
  756. $options['FIRST_ID'] = (int)$arParams['FIRST_ID'];
  757. }
  758. else
  759. {
  760. $options['LAST_ID'] = (
  761. isset($arParams['LAST_ID']) && (int)$arParams['LAST_ID'] > 0
  762. ? (int)$arParams['LAST_ID']
  763. : 0
  764. );
  765. }
  766. $options['LIMIT'] = (
  767. isset($arParams['LIMIT'])
  768. ? (
  769. (int)$arParams['LIMIT'] > 1000
  770. ? 1000
  771. : (int)$arParams['LIMIT'])
  772. : 100
  773. );
  774. $filter = [
  775. '=USER_ID' => $userId,
  776. '@EVENT_ID' => self::getBlogCommentEventId(),
  777. ];
  778. if (isset($options['FIRST_ID']))
  779. {
  780. $order = array();
  781. if ((int)$options['FIRST_ID'] > 0)
  782. {
  783. $filter['>ID'] = $options['FIRST_ID'];
  784. }
  785. }
  786. else
  787. {
  788. $order = Array('ID' => 'DESC');
  789. if (isset($options['LAST_ID']) && (int)$options['LAST_ID'] > 0)
  790. {
  791. $filter['<ID'] = (int)$options['LAST_ID'];
  792. }
  793. }
  794. $logCommentIdList = array();
  795. $res = Bitrix\Socialnetwork\LogCommentTable::getList(array(
  796. 'filter' => $filter,
  797. 'select' => array(
  798. 'ID', 'SOURCE_ID'
  799. ),
  800. 'order' => $order,
  801. 'limit' => $options['LIMIT']
  802. ));
  803. $commentIdList = [];
  804. while ($logCommentFields = $res->fetch())
  805. {
  806. if ((int)$logCommentFields['SOURCE_ID'] > 0)
  807. {
  808. $commentIdList[] = $logCommentFields['SOURCE_ID'];
  809. $logCommentIdList[$logCommentFields['SOURCE_ID']] = $logCommentFields['ID'];
  810. }
  811. }
  812. $commentIdList = array_unique($commentIdList);
  813. if (empty($commentIdList))
  814. {
  815. return $result;
  816. }
  817. $res = Bitrix\Blog\CommentTable::getList(array(
  818. 'filter' => array(
  819. '@ID' => $commentIdList
  820. ),
  821. 'select' => array(
  822. 'ID', 'AUTHOR_ID', 'POST_ID', 'DATE_CREATE', 'POST_TEXT', 'SHARE_DEST', 'UF_BLOG_COMMENT_FILE'
  823. ),
  824. 'order' => array('ID' => 'DESC')
  825. ));
  826. $attachedIdList = array();
  827. $commentAttachedList = array();
  828. $loadedSocialnetwork = Loader::includeModule('socialnetwork');
  829. while ($commentFields = $res->fetch())
  830. {
  831. $result['COMMENTS'][$commentFields['ID']] = array(
  832. 'ID' => (int)$logCommentIdList[$commentFields['ID']],
  833. 'COMMENT_ID' => (int)$commentFields['ID'],
  834. 'POST_ID' => (int)$commentFields['POST_ID'],
  835. 'DATE' => $commentFields['DATE_CREATE'],
  836. 'TEXT' => ($otherUserMode ? '' : (string)$commentFields['POST_TEXT']),
  837. 'ATTACH' => array()
  838. );
  839. if (
  840. $loadedSocialnetwork
  841. && ($commentAuxProvider = \Bitrix\Socialnetwork\CommentAux\Base::findProvider(
  842. $commentFields,
  843. array(
  844. "mobile" => false,
  845. "bPublicPage" => true,
  846. "cache" => true
  847. )
  848. )
  849. ))
  850. {
  851. $result['COMMENTS'][$commentFields['ID']]['TEXT'] = $commentAuxProvider->getText();
  852. }
  853. if (!empty($commentFields['UF_BLOG_COMMENT_FILE']))
  854. {
  855. if (is_array($commentFields['UF_BLOG_COMMENT_FILE']))
  856. {
  857. $attached = $commentFields['UF_BLOG_COMMENT_FILE'];
  858. }
  859. elseif ((int)$commentFields['UF_BLOG_COMMENT_FILE'] > 0)
  860. {
  861. $attached = [ (int)$commentFields['UF_BLOG_COMMENT_FILE'] ];
  862. }
  863. else
  864. {
  865. $attached = [];
  866. }
  867. if (!empty($attached))
  868. {
  869. $attachedIdList = array_merge($attachedIdList, $attached);
  870. }
  871. $commentAttachedList[$commentFields['ID']] = $attached;
  872. }
  873. }
  874. $attachedObjectList = array();
  875. if (
  876. !empty($attachedIdList)
  877. && Loader::includeModule('disk')
  878. )
  879. {
  880. $res = Bitrix\Disk\AttachedObject::getList(array(
  881. 'filter' => array(
  882. '@ID' => array_unique($attachedIdList)
  883. ),
  884. 'select' => array('ID', 'OBJECT_ID')
  885. ));
  886. while ($attachedObjectFields = $res->fetch())
  887. {
  888. $diskObjectId = $attachedObjectFields['OBJECT_ID'];
  889. if ($fileData = self::getFileData($diskObjectId))
  890. {
  891. $attachedObjectList[$attachedObjectFields['ID']] = $diskObjectId;
  892. $result['FILES'][$diskObjectId] = $fileData;
  893. }
  894. }
  895. }
  896. foreach ($result['COMMENTS'] as $key => $value)
  897. {
  898. if ($value['DATE'] instanceof \Bitrix\Main\Type\DateTime)
  899. {
  900. $result['COMMENTS'][$key]['DATE'] = date('c', $value['DATE']->getTimestamp());
  901. }
  902. if (!empty($commentAttachedList[$key]))
  903. {
  904. foreach ($commentAttachedList[$key] as $attachedId)
  905. {
  906. if (!empty($attachedObjectList[$attachedId]))
  907. {
  908. $result['COMMENTS'][$key]['ATTACH'][] = $attachedObjectList[$attachedId];
  909. }
  910. }
  911. }
  912. $result['COMMENTS'][$key] = array_change_key_case($result['COMMENTS'][$key], CASE_LOWER);
  913. }
  914. $result['COMMENTS'] = array_values($result['COMMENTS']);
  915. $result['FILES'] = self::convertFileData($result['FILES']);
  916. return $result;
  917. }
  918. public static function addBlogComment($fields): int
  919. {
  920. $authorId = (int)(
  921. isset($fields["USER_ID"])
  922. && (int)$fields["USER_ID"] > 0
  923. && self::isAdmin()
  924. ? $fields["USER_ID"]
  925. : self::getCurrentUserId()
  926. );
  927. if (!Loader::includeModule('blog'))
  928. {
  929. throw new Exception('No blog module installed');
  930. }
  931. $postId = (int)$fields['POST_ID'];
  932. if ($postId <= 0)
  933. {
  934. throw new Exception('No post found');
  935. }
  936. $res = CBlogPost::getList(
  937. array(),
  938. array(
  939. "ID" => $postId
  940. ),
  941. false,
  942. false,
  943. array("ID", "BLOG_ID", "AUTHOR_ID", "BLOG_OWNER_ID", "TITLE")
  944. );
  945. $post = $res->fetch();
  946. if (!$post)
  947. {
  948. throw new Exception('No post found');
  949. }
  950. $blog = CBlog::getById($post["BLOG_ID"]);
  951. if (!$blog)
  952. {
  953. throw new Exception('No blog found');
  954. }
  955. if (
  956. empty($fields["FILES"])
  957. && !\Bitrix\Blog\Item\Comment::checkDuplicate(array(
  958. 'MESSAGE' => $fields["TEXT"],
  959. 'BLOG_ID' => $post['BLOG_ID'],
  960. 'POST_ID' => $post['ID'],
  961. 'AUTHOR_ID' => $authorId,
  962. ))
  963. )
  964. {
  965. throw new Exception('Duplicate comment');
  966. }
  967. $userIP = CBlogUser::getUserIP();
  968. $commentFields = array(
  969. "POST_ID" => $post['ID'],
  970. "BLOG_ID" => $post['BLOG_ID'],
  971. "TITLE" => '',
  972. "POST_TEXT" => $fields["TEXT"],
  973. "DATE_CREATE" => convertTimeStamp(time() + CTimeZone::getOffset(), "FULL"),
  974. "AUTHOR_IP" => $userIP[0],
  975. "AUTHOR_IP1" => $userIP[1],
  976. "URL" => $blog["URL"],
  977. "PARENT_ID" => false,
  978. "SEARCH_GROUP_ID" => $blog['GROUP_ID'],
  979. "AUTHOR_ID" => $authorId
  980. );
  981. $perm = \Bitrix\Blog\Item\Permissions::DENY;
  982. if ((int)$post['AUTHOR_ID'] === $authorId)
  983. {
  984. $perm = \Bitrix\Blog\Item\Permissions::FULL;
  985. }
  986. else
  987. {
  988. $postPerm = CBlogPost::getSocNetPostPerms($post["ID"]);
  989. if ($postPerm > \Bitrix\Blog\Item\Permissions::DENY)
  990. {
  991. $perm = CBlogComment::getSocNetUserPerms($post["ID"], $post["AUTHOR_ID"]);
  992. }
  993. }
  994. if ($perm === \Bitrix\Blog\Item\Permissions::DENY)
  995. {
  996. throw new Exception('No permissions');
  997. }
  998. if ($perm === \Bitrix\Blog\Item\Permissions::PREMODERATE)
  999. {
  1000. $commentFields["PUBLISH_STATUS"] = BLOG_PUBLISH_STATUS_READY;
  1001. }
  1002. $result = CBlogComment::add($commentFields);
  1003. if (!$result)
  1004. {
  1005. throw new Exception('Blog comment hasn\'t been added');
  1006. }
  1007. if (
  1008. isset($fields["FILES"])
  1009. && Option::get('disk', 'successfully_converted', false)
  1010. && Loader::includeModule('disk')
  1011. && ($storage = \Bitrix\Disk\Driver::getInstance()->getStorageByUserId($authorId))
  1012. && ($folder = $storage->getFolderForUploadedFiles())
  1013. )
  1014. {
  1015. // upload to storage
  1016. $filesList = array();
  1017. foreach ($fields["FILES"] as $tmp)
  1018. {
  1019. $fileFields = CRestUtil::saveFile($tmp);
  1020. if (is_array($fileFields))
  1021. {
  1022. $file = $folder->uploadFile(
  1023. $fileFields, // file array
  1024. array(
  1025. 'NAME' => $fileFields["name"],
  1026. 'CREATED_BY' => $authorId
  1027. ),
  1028. array(),
  1029. true
  1030. );
  1031. if ($file)
  1032. {
  1033. $filesList[] = \Bitrix\Disk\Uf\FileUserType::NEW_FILE_PREFIX.$file->getId();
  1034. }
  1035. }
  1036. }
  1037. if (!empty($filesList)) // update post
  1038. {
  1039. CBlogComment::update(
  1040. $result,
  1041. array(
  1042. "HAS_PROPS" => "Y",
  1043. "UF_BLOG_COMMENT_FILE" => $filesList
  1044. )
  1045. );
  1046. }
  1047. }
  1048. \Bitrix\Blog\Item\Comment::actionsAfter(array(
  1049. 'MESSAGE' => $commentFields["POST_TEXT"],
  1050. 'BLOG_ID' => $post["BLOG_ID"],
  1051. 'BLOG_OWNER_ID' => $post["BLOG_OWNER_ID"],
  1052. 'POST_ID' => $post["ID"],
  1053. 'POST_TITLE' => $post["TITLE"],
  1054. 'POST_AUTHOR_ID' => $post["AUTHOR_ID"],
  1055. 'COMMENT_ID' => $result,
  1056. 'AUTHOR_ID' => $authorId,
  1057. ));
  1058. return $result;
  1059. }
  1060. public static function deleteBlogComment($fields): bool
  1061. {
  1062. $commentId = (int)$fields['COMMENT_ID'];
  1063. if ($commentId <= 0)
  1064. {
  1065. throw new Exception('Wrong comment ID');
  1066. }
  1067. if (!Loader::includeModule('blog'))
  1068. {
  1069. throw new Exception('Blog module not installed');
  1070. }
  1071. $currentUserId = (
  1072. isset($fields["USER_ID"])
  1073. && (int)$fields["USER_ID"] > 0
  1074. && self::isAdmin()
  1075. ? $fields["USER_ID"]
  1076. : self::getCurrentUserId()
  1077. );
  1078. $currentUserPerm = self::getBlogCommentPerm(array(
  1079. 'USER_ID' => $currentUserId,
  1080. 'COMMENT_ID' => $commentId
  1081. ));
  1082. if ($currentUserPerm < \Bitrix\Blog\Item\Permissions::FULL)
  1083. {
  1084. throw new Exception('No delete perms');
  1085. }
  1086. $commentFields = \Bitrix\Blog\Item\Comment::getById($commentId)->getFields();
  1087. if (empty($commentId))
  1088. {
  1089. throw new Exception('No comment found');
  1090. }
  1091. if ($result = CBlogComment::Delete($commentId))
  1092. {
  1093. BXClearCache(true, ComponentHelper::getBlogPostCacheDir(array(
  1094. 'TYPE' => 'post_comments',
  1095. 'POST_ID' => $commentFields["POST_ID"]
  1096. )));
  1097. CBlogComment::DeleteLog($commentId);
  1098. }
  1099. return (bool)$result;
  1100. }
  1101. public static function getUserLogComment($arParams, $offset, CRestServer $server): array
  1102. {
  1103. $arParams = array_change_key_case($arParams, CASE_UPPER);
  1104. $result = [
  1105. 'COMMENTS' => [],
  1106. 'FILES' => [],
  1107. ];
  1108. $userId = (int)(
  1109. isset($arParams["USER_ID"])
  1110. && (int)$arParams["USER_ID"] > 0
  1111. && self::isAdmin()
  1112. ? $arParams["USER_ID"]
  1113. : self::getCurrentUserId()
  1114. );
  1115. $otherUserMode = ($userId !== self::getCurrentUserId());
  1116. if ($userId <= 0)
  1117. {
  1118. throw new Bitrix\Rest\RestException("User ID can't be empty", "ID_EMPTY", CRestServer::STATUS_WRONG_REQUEST);
  1119. }
  1120. if (isset($arParams['FIRST_ID']))
  1121. {
  1122. $options['FIRST_ID'] = (int)$arParams['FIRST_ID'];
  1123. }
  1124. else
  1125. {
  1126. $options['LAST_ID'] = (
  1127. isset($arParams['LAST_ID'])
  1128. && (int)$arParams['LAST_ID'] > 0
  1129. ? (int)$arParams['LAST_ID']
  1130. : 0
  1131. );
  1132. }
  1133. $options['LIMIT'] = (
  1134. isset($arParams['LIMIT'])
  1135. ? (
  1136. (int)$arParams['LIMIT'] > 1000
  1137. ? 1000
  1138. : (int)$arParams['LIMIT'])
  1139. : 100
  1140. );
  1141. $filter = array(
  1142. '=USER_ID' => $userId,
  1143. '@EVENT_ID' => self::getLogCommentEventId()
  1144. );
  1145. if (isset($options['FIRST_ID']))
  1146. {
  1147. $order = array();
  1148. if ((int)$options['FIRST_ID'] > 0)
  1149. {
  1150. $filter['>ID'] = $options['FIRST_ID'];
  1151. }
  1152. }
  1153. else
  1154. {
  1155. $order = [ 'ID' => 'DESC' ];
  1156. if (isset($options['LAST_ID']) && (int)$options['LAST_ID'] > 0)
  1157. {
  1158. $filter['<ID'] = (int)$options['LAST_ID'];
  1159. }
  1160. }
  1161. $res = Bitrix\Socialnetwork\LogCommentTable::getList(array(
  1162. 'filter' => $filter,
  1163. 'select' => array(
  1164. 'ID', 'LOG_ID', 'LOG_DATE', 'MESSAGE', 'UF_SONET_COM_DOC'
  1165. ),
  1166. 'order' => $order,
  1167. 'limit' => $options['LIMIT']
  1168. ));
  1169. $attachedIdList = array();
  1170. while ($commentFields = $res->fetch())
  1171. {
  1172. $result['COMMENTS'][$commentFields['ID']] = array(
  1173. 'ID' => (int)$commentFields['ID'],
  1174. 'COMMENT_ID' => (int)$commentFields['ID'],
  1175. 'LOG_ID' => (int)$commentFields['LOG_ID'],
  1176. 'DATE' => $commentFields['LOG_DATE'],
  1177. 'TEXT' => ($otherUserMode ? '' : (string)$commentFields['MESSAGE']),
  1178. 'ATTACH' => array()
  1179. );
  1180. if (!empty($commentFields['UF_SONET_COM_DOC']))
  1181. {
  1182. if (is_array($commentFields['UF_SONET_COM_DOC']))
  1183. {
  1184. $attached = $commentFields['UF_SONET_COM_DOC'];
  1185. }
  1186. elseif ((int)$commentFields['UF_SONET_COM_DOC'] > 0)
  1187. {
  1188. $attached = array((int)$commentFields['UF_SONET_COM_DOC']);
  1189. }
  1190. else
  1191. {
  1192. $attached = array();
  1193. }
  1194. if (!empty($attached))
  1195. {
  1196. $attachedIdList = array_merge($attachedIdList, $attached);
  1197. }
  1198. $commentAttachedList[$commentFields['ID']] = $attached;
  1199. }
  1200. }
  1201. $attachedObjectList = array();
  1202. if (
  1203. !empty($attachedIdList)
  1204. && Loader::includeModule('disk')
  1205. )
  1206. {
  1207. $res = Bitrix\Disk\AttachedObject::getList(array(
  1208. 'filter' => array(
  1209. '@ID' => array_unique($attachedIdList)
  1210. ),
  1211. 'select' => array('ID', 'OBJECT_ID')
  1212. ));
  1213. while ($attachedObjectFields = $res->fetch())
  1214. {
  1215. $diskObjectId = $attachedObjectFields['OBJECT_ID'];
  1216. if ($fileData = self::getFileData($diskObjectId))
  1217. {
  1218. $attachedObjectList[$attachedObjectFields['ID']] = $diskObjectId;
  1219. $result['FILES'][$diskObjectId] = $fileData;
  1220. }
  1221. }
  1222. }
  1223. foreach ($result['COMMENTS'] as $key => $value)
  1224. {
  1225. if ($value['DATE'] instanceof \Bitrix\Main\Type\DateTime)
  1226. {
  1227. $result['COMMENTS'][$key]['DATE'] = date('c', $value['DATE']->getTimestamp());
  1228. }
  1229. if (!empty($commentAttachedList[$key]))
  1230. {
  1231. foreach ($commentAttachedList[$key] as $attachedId)
  1232. {
  1233. if (!empty($attachedObjectList[$attachedId]))
  1234. {
  1235. $result['COMMENTS'][$key]['ATTACH'][] = $attachedObjectList[$attachedId];
  1236. }
  1237. }
  1238. }
  1239. $result['COMMENTS'][$key] = array_change_key_case($result['COMMENTS'][$key], CASE_LOWER);
  1240. }
  1241. $result['COMMENTS'] = array_values($result['COMMENTS']);
  1242. $result['FILES'] = self::convertFileData($result['FILES']);
  1243. return $result;
  1244. }
  1245. public static function deleteLogComment($arFields): bool
  1246. {
  1247. $commentId = (int)$arFields['COMMENT_ID'];
  1248. if ($commentId <= 0)
  1249. {
  1250. throw new Exception('Wrong comment ID');
  1251. }
  1252. $currentUserId = (
  1253. isset($arFields["USER_ID"])
  1254. && (int)$arFields["USER_ID"] > 0
  1255. && self::isAdmin()
  1256. ? $arFields["USER_ID"]
  1257. : self::getCurrentUserId()
  1258. );
  1259. $commentFields = \Bitrix\Socialnetwork\Item\LogComment::getById($commentId)->getFields();
  1260. if (empty($commentFields))
  1261. {
  1262. throw new Exception('No comment found');
  1263. }
  1264. $currentUserPerm = self::getLogCommentPerm(array(
  1265. 'USER_ID' => $currentUserId,
  1266. 'COMMENT_ID' => $commentId
  1267. ));
  1268. if ($currentUserPerm < self::PERM_WRITE)
  1269. {
  1270. throw new Exception('No write perms');
  1271. }
  1272. $result = CSocNetLogComments::Delete($commentId);
  1273. return (bool)$result;
  1274. }
  1275. private static function getBlogPostPerm($fields)
  1276. {
  1277. return Helper::getBlogPostPerm($fields);
  1278. }
  1279. private static function getBlogCommentPerm($fields)
  1280. {
  1281. if (!Loader::includeModule('blog'))
  1282. {
  1283. throw new Exception('Blog module not installed');
  1284. }
  1285. $result = Bitrix\Blog\Item\Permissions::DENY;
  1286. $commentId = $fields['COMMENT_ID'];
  1287. $currentUserId = (int)(
  1288. isset($fields["USER_ID"])
  1289. && (int)$fields['USER_ID'] > 0
  1290. && self::isAdmin()
  1291. ? $fields["USER_ID"]
  1292. : self::getCurrentUserId()
  1293. );
  1294. $arComment = self::getBlogCommentFields($commentId);
  1295. if (empty($arComment))
  1296. {
  1297. return $result;
  1298. }
  1299. if ((int)$arComment["AUTHOR_ID"] === $currentUserId)
  1300. {
  1301. $result = Bitrix\Blog\Item\Permissions::FULL;
  1302. }
  1303. elseif (CSocNetUser::isUserModuleAdmin($currentUserId, SITE_ID))
  1304. {
  1305. $result = Bitrix\Blog\Item\Permissions::FULL;
  1306. }
  1307. elseif ($arComment['PUBLISH_STATUS'] === BLOG_PUBLISH_STATUS_PUBLISH)
  1308. {
  1309. $postItem = \Bitrix\Blog\Item\Post::getById($arComment['POST_ID']);
  1310. $permsResult = $postItem->getSonetPerms(array(
  1311. "CHECK_FULL_PERMS" => true
  1312. ));
  1313. $result = $permsResult['PERM'];
  1314. if (
  1315. $result <= \Bitrix\Blog\Item\Permissions::READ
  1316. && $permsResult['READ_BY_OSG']
  1317. )
  1318. {
  1319. $result = Bitrix\Blog\Item\Permissions::READ;
  1320. }
  1321. elseif ($result > \Bitrix\Blog\Item\Permissions::READ)
  1322. {
  1323. $result = \Bitrix\Blog\Item\Permissions::READ;
  1324. }
  1325. }
  1326. return $result;
  1327. }
  1328. private static function getLogCommentPerm($arFields): string
  1329. {
  1330. $result = self::PERM_DENY;
  1331. $commentId = $arFields['COMMENT_ID'];
  1332. $currentUserId = (int)(
  1333. isset($arFields["USER_ID"])
  1334. && (int)$arFields["USER_ID"] > 0
  1335. && self::isAdmin()
  1336. ? $arFields["USER_ID"]
  1337. : self::getCurrentUserId()
  1338. );
  1339. if (
  1340. CSocNetUser::isUserModuleAdmin($currentUserId, SITE_ID)
  1341. || (
  1342. ($arComment = self::getLogCommentFields($commentId))
  1343. && (int)$arComment['USER_ID'] === $currentUserId
  1344. )
  1345. )
  1346. {
  1347. $result = self::PERM_WRITE;
  1348. }
  1349. return $result;
  1350. }
  1351. private static function getBlogCommentFields($commentId): array
  1352. {
  1353. $result = array();
  1354. if ($commentItem = \Bitrix\Blog\Item\Comment::getById($commentId))
  1355. {
  1356. $result = $commentItem->getFields();
  1357. }
  1358. return $result;
  1359. }
  1360. private static function getLogCommentFields($commentId): array
  1361. {
  1362. $result = array();
  1363. if ($commentItem = \Bitrix\Socialnetwork\Item\LogComment::getById($commentId))
  1364. {
  1365. $result = $commentItem->getFields();
  1366. }
  1367. return $result;
  1368. }
  1369. private static function getFileData($diskObjectId)
  1370. {
  1371. $result = false;
  1372. $diskObjectId = (int)$diskObjectId;
  1373. if ($diskObjectId <= 0)
  1374. {
  1375. return $result;
  1376. }
  1377. if ($fileModel = \Bitrix\Disk\File::getById($diskObjectId))
  1378. {
  1379. /** @var \Bitrix\Disk\File $fileModel */
  1380. $contentType = 'file';
  1381. $imageParams = false;
  1382. if (\Bitrix\Disk\TypeFile::isImage($fileModel->getName()))
  1383. {
  1384. $contentType = 'image';
  1385. $params = $fileModel->getFile();
  1386. $imageParams = Array(
  1387. 'width' => (int)$params['WIDTH'],
  1388. 'height' => (int)$params['HEIGHT'],
  1389. );
  1390. }
  1391. else if (\Bitrix\Disk\TypeFile::isVideo($fileModel->getName()))
  1392. {
  1393. $contentType = 'video';
  1394. $params = $fileModel->getView()->getPreviewData();
  1395. $imageParams = Array(
  1396. 'width' => (int)$params['WIDTH'],
  1397. 'height' => (int)$params['HEIGHT'],
  1398. );
  1399. }
  1400. $isImage = \Bitrix\Disk\TypeFile::isImage($fileModel);
  1401. $urlManager = \Bitrix\Disk\Driver::getInstance()->getUrlManager();
  1402. $result = array(
  1403. 'id' => (int)$fileModel->getId(),
  1404. 'date' => $fileModel->getCreateTime(),
  1405. 'type' => $contentType,
  1406. 'name' => $fileModel->getName(),
  1407. 'size' => (int)$fileModel->getSize(),
  1408. 'image' => $imageParams,
  1409. 'authorId' => (int)$fileModel->getCreatedBy(),
  1410. 'authorName' => CUser::FormatName(CSite::getNameFormat(false), $fileModel->getCreateUser(), true, true),
  1411. 'urlPreview' => (
  1412. $fileModel->getPreviewId()
  1413. ? $urlManager->getUrlForShowPreview($fileModel, [ 'width' => 640, 'height' => 640])
  1414. : (
  1415. $isImage
  1416. ? $urlManager->getUrlForShowFile($fileModel, [ 'width' => 640, 'height' => 640])
  1417. : null
  1418. )
  1419. ),
  1420. 'urlShow' => ($isImage ? $urlManager->getUrlForShowFile($fileModel) : $urlManager->getUrlForDownloadFile($fileModel)),
  1421. 'urlDownload' => $urlManager->getUrlForDownloadFile($fileModel)
  1422. );
  1423. }
  1424. return $result;
  1425. }
  1426. private static function convertFileData($fileData): array
  1427. {
  1428. if (!is_array($fileData))
  1429. {
  1430. return array();
  1431. }
  1432. foreach ($fileData as $key => $value)
  1433. {
  1434. if ($value['date'] instanceof \Bitrix\Main\Type\DateTime)
  1435. {
  1436. $fileData[$key]['date'] = date('c', $value['date']->getTimestamp());
  1437. }
  1438. foreach (['urlPreview', 'urlShow', 'urlDownload'] as $field)
  1439. {
  1440. $url = $fileData[$key][$field];
  1441. if (is_string($url) && $url && mb_strpos($url, 'http') !== 0)
  1442. {
  1443. $fileData[$key][$field] = self::getPublicDomain().$url;
  1444. }
  1445. }
  1446. }
  1447. return $fileData;
  1448. }
  1449. private static function getPublicDomain(): ?string
  1450. {
  1451. static $result = null;
  1452. if ($result === null)
  1453. {
  1454. $result = (\Bitrix\Main\Context::getCurrent()->getRequest()->isHttps() ? "https" : "http")."://".((defined("SITE_SERVER_NAME") && SITE_SERVER_NAME <> '') ? SITE_SERVER_NAME : Option::get("main", "server_name", $_SERVER['SERVER_NAME']));
  1455. }
  1456. return $result;
  1457. }
  1458. public static function createGroup($fields)
  1459. {
  1460. if (!is_array($fields))
  1461. {
  1462. throw new Exception('Incorrect input data');
  1463. }
  1464. foreach ($fields as $key => $value)
  1465. {
  1466. if (in_array(mb_substr($key, 0, 1), [ '~', '=' ]))
  1467. {
  1468. unset($fields[$key]);
  1469. }
  1470. }
  1471. if (isset($fields['IMAGE_FILE_ID']) && Loader::includeModule('disk'))
  1472. {
  1473. if (
  1474. (($imageFileId = (int)$fields['IMAGE_FILE_ID']) > 0)
  1475. && ($file = File::loadById($imageFileId))
  1476. && $file->canRead($file->getStorage()->getSecurityContext(self::getCurrentUserId()))
  1477. )
  1478. {
  1479. $image = \CFile::MakeFileArray($file->getFileId());
  1480. $image['del'] = 'N';
  1481. \CFile::ResizeImage($image, ['width' => 300, 'height' => 300]);
  1482. $fields['IMAGE_ID'] = $image;
  1483. unset($fields['IMAGE']);
  1484. }
  1485. else
  1486. {
  1487. unset($fields['IMAGE_FILE_ID']);
  1488. }
  1489. }
  1490. if (isset($fields['IMAGE']))
  1491. {
  1492. $fields['IMAGE_ID'] = CRestUtil::saveFile($fields['IMAGE']);
  1493. if (!$fields['IMAGE_ID'])
  1494. {
  1495. unset($fields['IMAGE_ID']);
  1496. }
  1497. unset($fields['IMAGE']);
  1498. }
  1499. if (
  1500. !is_set($fields, "SITE_ID")
  1501. || (string)$fields["SITE_ID"] === ''
  1502. )
  1503. {
  1504. $fields["SITE_ID"] = array(SITE_ID);
  1505. }
  1506. if (
  1507. !is_set($fields, "SUBJECT_ID")
  1508. || (int)$fields["SUBJECT_ID"] <= 0
  1509. )
  1510. {
  1511. $rsSubject = CSocNetGroupSubject::GetList(
  1512. array("SORT" => "ASC"),
  1513. array("SITE_ID" => $fields["SITE_ID"]),
  1514. false,
  1515. false,
  1516. array("ID")
  1517. );
  1518. if ($arSubject = $rsSubject->Fetch())
  1519. {
  1520. $fields["SUBJECT_ID"] = $arSubject["ID"];
  1521. }
  1522. }
  1523. $initiatePerms = [
  1524. UserToGroupTable::ROLE_OWNER,
  1525. UserToGroupTable::ROLE_MODERATOR,
  1526. UserToGroupTable::ROLE_USER,
  1527. ];
  1528. if (
  1529. !isset($fields['INITIATE_PERMS'])
  1530. || !in_array($fields['INITIATE_PERMS'], $initiatePerms, true)
  1531. )
  1532. {
  1533. $isExtranetInstalled = (
  1534. ModuleManager::isModuleInstalled('intranet')
  1535. && ModuleManager::isModuleInstalled('extranet')
  1536. && !empty(Option::get('extranet', 'extranet_site'))
  1537. );
  1538. $isExtranet = (
  1539. $isExtranetInstalled
  1540. && Loader::includeModule('extranet')
  1541. && \CExtranet::IsExtranetSite()
  1542. );
  1543. $fields['INITIATE_PERMS'] = ($isExtranet ? UserToGroupTable::ROLE_MODERATOR : UserToGroupTable::ROLE_USER);
  1544. }
  1545. if (!empty($fields['PROJECT_DATE_START']))
  1546. {
  1547. $fields['PROJECT_DATE_START'] = CRestUtil::unConvertDate($fields['PROJECT_DATE_START']);
  1548. }
  1549. if (!empty($fields['PROJECT_DATE_FINISH']))
  1550. {
  1551. $fields['PROJECT_DATE_FINISH'] = CRestUtil::unConvertDate($fields['PROJECT_DATE_FINISH']);
  1552. }
  1553. $ownerId = (
  1554. !empty($fields['OWNER_ID'])
  1555. && (int)$fields['OWNER_ID'] > 0
  1556. && self::isCurrentUserAdmin()
  1557. ? (int)$fields['OWNER_ID']
  1558. : self::getCurrentUserId()
  1559. );
  1560. Workgroup::mutateScrumFormFields($fields);
  1561. $groupId = CSocNetGroup::createGroup($ownerId, $fields, false);
  1562. if ($groupId <= 0)
  1563. {
  1564. throw new Exception('Cannot create group');
  1565. }
  1566. else
  1567. {
  1568. CSocNetFeatures::SetFeature(
  1569. SONET_ENTITY_GROUP,
  1570. $groupId,
  1571. 'files',
  1572. true
  1573. );
  1574. if (
  1575. isset($fields['GROUP_THEME_ID'])
  1576. && Loader::includeModule('intranet')
  1577. )
  1578. {
  1579. $siteTemplateId = 'bitrix24';
  1580. if ($themePicker = new ThemePicker($siteTemplateId, SITE_ID, self::getCurrentUserId(), ThemePicker::ENTITY_TYPE_SONET_GROUP, $groupId))
  1581. {
  1582. if (empty($fields['GROUP_THEME_ID']))
  1583. {
  1584. $themesList = $themePicker->getPatternThemes();
  1585. $themePickerData = $themesList[array_rand($themesList)];
  1586. $fields['GROUP_THEME_ID'] = $themePickerData['id'];
  1587. }
  1588. try
  1589. {
  1590. $themePicker->setCurrentThemeId($fields['GROUP_THEME_ID']);
  1591. unset($themePicker);
  1592. }
  1593. catch (\Bitrix\Main\ArgumentException $exception)
  1594. {
  1595. }
  1596. }
  1597. }
  1598. }
  1599. return $groupId;
  1600. }
  1601. public static function updateGroup($arFields)
  1602. {
  1603. foreach ($arFields as $key => $value)
  1604. {
  1605. if (in_array(mb_substr($key, 0, 1), [ '~', '=' ]))
  1606. {
  1607. unset($arFields[$key]);
  1608. }
  1609. }
  1610. if (isset($arFields['IMAGE_FILE_ID']) && Loader::includeModule('disk'))
  1611. {
  1612. $imageFileId = (int)$arFields['IMAGE_FILE_ID'];
  1613. if ($imageFileId === 0)
  1614. {
  1615. $arFields['IMAGE_ID'] = ['del' => 'Y'];
  1616. unset($arFields['IMAGE']);
  1617. }
  1618. else if (
  1619. $imageFileId > 0
  1620. && ($file = File::loadById($imageFileId))
  1621. && $file->canRead($file->getStorage()->getSecurityContext(self::getCurrentUserId()))
  1622. )
  1623. {
  1624. $image = \CFile::MakeFileArray($file->getFileId());
  1625. $image['del'] = 'N';
  1626. \CFile::ResizeImage($image, ['width' => 300, 'height' => 300]);
  1627. $arFields['IMAGE_ID'] = $image;
  1628. unset($arFields['IMAGE']);
  1629. }
  1630. else
  1631. {
  1632. unset($arFields['IMAGE_FILE_ID']);
  1633. }
  1634. }
  1635. if (isset($arFields['IMAGE']))
  1636. {
  1637. $arFields['IMAGE_ID'] = CRestUtil::saveFile($arFields['IMAGE']);
  1638. if (!$arFields['IMAGE_ID'])
  1639. {
  1640. $arFields['IMAGE_ID'] = array('del' => 'Y');
  1641. }
  1642. unset($arFields['IMAGE']);
  1643. }
  1644. if (!empty($arFields['PROJECT_DATE_START']))
  1645. {
  1646. $arFields['PROJECT_DATE_START'] = CRestUtil::unConvertDate($arFields['PROJECT_DATE_START']);
  1647. }
  1648. if (!empty($arFields['PROJECT_DATE_FINISH']))
  1649. {
  1650. $arFields['PROJECT_DATE_FINISH'] = CRestUtil::unConvertDate($arFields['PROJECT_DATE_FINISH']);
  1651. }
  1652. $groupID = $arFields['GROUP_ID'];
  1653. unset($arFields['GROUP_ID']);
  1654. if ((int)$groupID <= 0)
  1655. {
  1656. throw new Exception('Wrong group ID');
  1657. }
  1658. if (!Workgroup::canUpdate([
  1659. 'groupId' => $groupID,
  1660. ]))
  1661. {
  1662. throw new Exception('User has no permissions to update group');
  1663. }
  1664. $res = CSocNetGroup::Update($groupID, $arFields, false);
  1665. if ((int)$res <= 0)
  1666. {
  1667. throw new Exception('Cannot update group');
  1668. }
  1669. return $res;
  1670. }
  1671. public static function deleteGroup($arFields): bool
  1672. {
  1673. $groupId = (int)$arFields['GROUP_ID'];
  1674. if ($groupId <= 0)
  1675. {
  1676. throw new Exception('Wrong group ID');
  1677. }
  1678. $filter = [
  1679. 'ID' => $groupId,
  1680. ];
  1681. if (!self::isCurrentUserAdmin())
  1682. {
  1683. $filter['CHECK_PERMISSIONS'] = self::getCurrentUserId();
  1684. }
  1685. $res = CSocNetGroup::GetList([], $filter);
  1686. $groupFiels = $res->Fetch();
  1687. if (is_array($groupFiels))
  1688. {
  1689. if (
  1690. (int)$groupFiels["OWNER_ID"] === self::getCurrentUserId()
  1691. || self::isCurrentUserAdmin()
  1692. )
  1693. {
  1694. if (!CSocNetGroup::Delete($groupFiels["ID"]))
  1695. {
  1696. throw new Exception('Cannot delete group');
  1697. }
  1698. }
  1699. else
  1700. {
  1701. throw new Exception('User has no permissions to delete group');
  1702. }
  1703. }
  1704. else
  1705. {
  1706. throw new Exception('Socialnetwork group not found');
  1707. }
  1708. return true;
  1709. }
  1710. public static function setGroupOwner($arFields): bool
  1711. {
  1712. try
  1713. {
  1714. return Workgroup::setOwner([
  1715. 'groupId' => $arFields['GROUP_ID'],
  1716. 'userId' => $arFields['USER_ID'],
  1717. ]);
  1718. }
  1719. catch(Exception $e)
  1720. {
  1721. throw new Exception($e->getMessage(), $e->getCode());
  1722. }
  1723. }
  1724. public static function getGroup($arFields, $n, $server)
  1725. {
  1726. $arOrder = $arFields['ORDER'];
  1727. if (!is_array($arOrder))
  1728. {
  1729. $arOrder = array("ID" => "DESC");
  1730. }
  1731. if (
  1732. $arFields['IS_ADMIN'] === 'Y'
  1733. && !self::isCurrentUserAdmin()
  1734. )
  1735. {
  1736. unset($arFields['IS_ADMIN']);
  1737. }
  1738. $filter = self::checkGroupFilter($arFields['FILTER']);
  1739. if (
  1740. isset($arFields['GROUP_ID'])
  1741. && (int)$arFields['GROUP_ID'] > 0
  1742. )
  1743. {
  1744. $filter['ID'] = $arFields['GROUP_ID'];
  1745. }
  1746. if ($arFields['IS_ADMIN'] !== 'Y')
  1747. {
  1748. $filter['CHECK_PERMISSIONS'] = self::getCurrentUserId();
  1749. }
  1750. $extranetSiteId = self::getExtranetSiteId();
  1751. if (
  1752. $extranetSiteId
  1753. && $arFields['IS_ADMIN'] !== 'Y'
  1754. && self::getCurrentUserType() === 'extranet'
  1755. )
  1756. {
  1757. $filter['SITE_ID'] = $extranetSiteId;
  1758. }
  1759. $result = [];
  1760. $res = CSocNetGroup::GetList($arOrder, $filter, false, self::getNavData($n));
  1761. while ($groupFields = $res->Fetch())
  1762. {
  1763. if (!empty($groupFields['NAME']))
  1764. {
  1765. $groupFields['NAME'] = Emoji::decode($groupFields['NAME']);
  1766. }
  1767. if (!empty($groupFields['DESCRIPTION']))
  1768. {
  1769. $groupFields['DESCRIPTION'] = Emoji::decode($groupFields['DESCRIPTION']);
  1770. }
  1771. $groupFields['DATE_CREATE'] = CRestUtil::ConvertDateTime($groupFields['DATE_CREATE']);
  1772. $groupFields['DATE_UPDATE'] = CRestUtil::ConvertDateTime($groupFields['DATE_UPDATE']);
  1773. $groupFields['DATE_ACTIVITY'] = CRestUtil::ConvertDate