PageRenderTime 27ms CodeModel.GetById 12ms RepoModel.GetById 1ms app.codeStats 0ms

/modules/socialservices/lib/contact.php

https://gitlab.com/alexprowars/bitrix
PHP | 679 lines | 530 code | 69 blank | 80 comment | 55 complexity | 1a0b66aedcad8fc5f675cfdefc906174 MD5 | raw file
  1. <?php
  2. namespace Bitrix\Socialservices;
  3. use Bitrix\Main;
  4. use Bitrix\Main\Config\Option;
  5. use Bitrix\Main\Localization\Loc;
  6. use Bitrix\Main\Entity;
  7. use Bitrix\Main\Type\DateTime;
  8. Loc::loadMessages(__FILE__);
  9. /**
  10. * Class ContactTable
  11. *
  12. * Fields:
  13. * <ul>
  14. * <li> ID int mandatory
  15. * <li> TIMESTAMP_X datetime optional default 'CURRENT_TIMESTAMP'
  16. * <li> USER_ID int mandatory
  17. * <li> CONTACT_USER_ID int optional
  18. * <li> CONTACT_XML_ID int optional
  19. * <li> CONTACT_NAME string(255) optional
  20. * <li> CONTACT_LAST_NAME string(255) optional
  21. * <li> CONTACT_PHOTO string(255) optional
  22. * <li> NOTIFY bool optional default 'N'
  23. * </ul>
  24. *
  25. * @package Bitrix\Socialservices
  26. *
  27. * DO NOT WRITE ANYTHING BELOW THIS
  28. *
  29. * <<< ORMENTITYANNOTATION
  30. * @method static EO_Contact_Query query()
  31. * @method static EO_Contact_Result getByPrimary($primary, array $parameters = array())
  32. * @method static EO_Contact_Result getById($id)
  33. * @method static EO_Contact_Result getList(array $parameters = array())
  34. * @method static EO_Contact_Entity getEntity()
  35. * @method static \Bitrix\Socialservices\EO_Contact createObject($setDefaultValues = true)
  36. * @method static \Bitrix\Socialservices\EO_Contact_Collection createCollection()
  37. * @method static \Bitrix\Socialservices\EO_Contact wakeUpObject($row)
  38. * @method static \Bitrix\Socialservices\EO_Contact_Collection wakeUpCollection($rows)
  39. */
  40. class ContactTable extends Main\Entity\DataManager
  41. {
  42. const NOTIFY = 'Y';
  43. const DONT_NOTIFY = 'N';
  44. const NOTIFY_CONTACT_COUNT = 3;
  45. const NOTIFY_POSSIBLE_COUNT = 3;
  46. const POSSIBLE_LAST_AUTHORIZE_LIMIT = '-1 weeks';
  47. const POSSIBLE_RESET_TIME = 2592000; // 86400 * 30
  48. const POSSIBLE_RESET_TIME_KEY = "_ts";
  49. protected static $notifyStack = array();
  50. /**
  51. * Returns DB table name for entity.
  52. *
  53. * @return string
  54. */
  55. public static function getTableName()
  56. {
  57. return 'b_socialservices_contact';
  58. }
  59. /**
  60. * Returns entity map definition.
  61. *
  62. * @return array
  63. */
  64. public static function getMap()
  65. {
  66. return array(
  67. 'ID' => array(
  68. 'data_type' => 'integer',
  69. 'primary' => true,
  70. 'autocomplete' => true,
  71. ),
  72. 'TIMESTAMP_X' => array(
  73. 'data_type' => 'datetime',
  74. ),
  75. 'USER_ID' => array(
  76. 'data_type' => 'integer',
  77. 'required' => true,
  78. ),
  79. 'CONTACT_USER_ID' => array(
  80. 'data_type' => 'integer',
  81. ),
  82. 'CONTACT_XML_ID' => array(
  83. 'data_type' => 'integer',
  84. ),
  85. 'CONTACT_NAME' => array(
  86. 'data_type' => 'string',
  87. ),
  88. 'CONTACT_LAST_NAME' => array(
  89. 'data_type' => 'string',
  90. ),
  91. 'CONTACT_PHOTO' => array(
  92. 'data_type' => 'string',
  93. ),
  94. 'LAST_AUTHORIZE' => array(
  95. 'data_type' => 'datetime',
  96. ),
  97. 'NOTIFY' => array(
  98. 'data_type' => 'boolean',
  99. 'values' => array(static::DONT_NOTIFY, static::NOTIFY),
  100. ),
  101. 'USER' => array(
  102. 'data_type' => 'Bitrix\Main\UserTable',
  103. 'reference' => array('=this.USER_ID' => 'ref.ID'),
  104. ),
  105. 'CONTACT_USER' => array(
  106. 'data_type' => 'Bitrix\Main\UserTable',
  107. 'reference' => array('=this.CONTACT_USER_ID' => 'ref.ID'),
  108. ),
  109. );
  110. }
  111. public static function onBeforeUpdate(Entity\Event $event)
  112. {
  113. $result = new Entity\EventResult();
  114. $data = $event->getParameter("fields");
  115. if(!isset($data['TIMESTAMP_X']))
  116. {
  117. $data['TIMESTAMP_X'] = new DateTime();
  118. $result->modifyFields($data);
  119. }
  120. }
  121. /**
  122. * @deprecated
  123. */
  124. public static function onUserLoginSocserv($params)
  125. {
  126. global $USER;
  127. if(
  128. $params['EXTERNAL_AUTH_ID'] === \CSocServBitrix24Net::ID
  129. && \Bitrix\Main\ModuleManager::isModuleInstalled('bitrix24')
  130. )
  131. {
  132. $notificationOptions = \CUserOptions::getOption("socialservices", "notifications", array());
  133. $lastDate = 0;
  134. if(isset($notificationOptions["CONTACTS_NOTIFY_DATE"]))
  135. {
  136. $lastDate = $notificationOptions["CONTACTS_NOTIFY_DATE"];
  137. }
  138. if($lastDate < time() - 86400)
  139. {
  140. static::notifyPossible($USER->getId());
  141. $notificationOptions["CONTACTS_NOTIFY_DATE"] = time();
  142. \CUserOptions::setOption("socialservices", "notifications", $notificationOptions);
  143. }
  144. }
  145. }
  146. public static function onNetworkBroadcast($data)
  147. {
  148. $contactsList = array();
  149. $possibleContactsList = array();
  150. if(isset($data["contact"]) && is_array($data["contact"]))
  151. {
  152. foreach($data["contact"] as $contact)
  153. {
  154. if(!isset($contactsList[$contact['CONTACT_OWNER']]))
  155. {
  156. $contactsList[$contact['CONTACT_OWNER']] = array();
  157. }
  158. $contactsList[$contact['CONTACT_OWNER']][] = $contact;
  159. }
  160. }
  161. if(isset($data["contact_possible"]) && is_array($data["contact_possible"]))
  162. {
  163. foreach($data["contact_possible"] as $contact)
  164. {
  165. if(!isset($possibleContactsList[$contact['CONTACT_OWNER']]))
  166. {
  167. $possibleContactsList[$contact['CONTACT_OWNER']] = array();
  168. }
  169. $possibleContactsList[$contact['CONTACT_OWNER']][] = $contact;
  170. }
  171. }
  172. $dbRes = UserTable::getList(array(
  173. 'filter' => array(
  174. '=EXTERNAL_AUTH_ID' => \CSocServBitrix24Net::ID,
  175. '=XML_ID' => array_unique(
  176. array_merge(
  177. array_keys($contactsList),
  178. array_keys($possibleContactsList)
  179. )
  180. ),
  181. ),
  182. 'select' => array('ID', 'USER_ID', 'XML_ID')
  183. ));
  184. while($owner = $dbRes->fetch())
  185. {
  186. if(
  187. count($contactsList) > 0
  188. && count($contactsList[$owner["XML_ID"]]) > 0
  189. )
  190. {
  191. static::processContacts($owner, $contactsList[$owner["XML_ID"]]);
  192. }
  193. if(
  194. count($possibleContactsList) > 0
  195. && count($possibleContactsList[$owner["XML_ID"]]) > 0
  196. )
  197. {
  198. static::processPossibleContacts($owner, $possibleContactsList[$owner["XML_ID"]]);
  199. }
  200. }
  201. }
  202. protected static function processContacts($owner, array $contactsList)
  203. {
  204. if(!Main\Loader::includeModule('rest'))
  205. {
  206. return;
  207. }
  208. $existedContacts = array();
  209. $dbRes = ContactTable::getList(array(
  210. 'filter' => array(
  211. '=USER_ID' => $owner["USER_ID"],
  212. ),
  213. 'select' => array('ID', 'CONTACT_XML_ID')
  214. ));
  215. while($existedContact = $dbRes->fetch())
  216. {
  217. $existedContacts[$existedContact['CONTACT_XML_ID']] = $existedContact['ID'];
  218. }
  219. foreach($contactsList as $contact)
  220. {
  221. $contactFields = array(
  222. "USER_ID" => $owner["USER_ID"],
  223. "CONTACT_XML_ID" => $contact["CONTACT_ID"],
  224. "CONTACT_NAME" => $contact["NAME"],
  225. "CONTACT_LAST_NAME" => $contact["LAST_NAME"],
  226. "CONTACT_PHOTO" => $contact["PHOTO"],
  227. "NOTIFY" => $contact["NOTIFY"],
  228. "LAST_AUTHORIZE" => DateTime::createFromUserTime(\CRestUtil::unConvertDateTime($contact['LAST_AUTHORIZE'])),
  229. );
  230. $contactId = false;
  231. if(isset($existedContacts[$contactFields["CONTACT_XML_ID"]]))
  232. {
  233. $contactId = $existedContacts[$contactFields["CONTACT_XML_ID"]];
  234. $result = static::update($contactId, $contactFields);
  235. if(!$result->isSuccess())
  236. {
  237. AddMessage2Log($result->getErrorMessages());
  238. }
  239. }
  240. else
  241. {
  242. $result = static::add($contactFields);
  243. if($result->isSuccess())
  244. {
  245. $contactId = $result->getId();
  246. }
  247. else
  248. {
  249. AddMessage2Log($result->getErrorMessages());
  250. }
  251. }
  252. if(
  253. $contactId > 0
  254. && isset($contact["profile"])
  255. && count($contact["profile"]) > 0
  256. )
  257. {
  258. if(isset($existedContacts[$contactFields["CONTACT_XML_ID"]]))
  259. {
  260. ContactConnectTable::deleteByContact($contactId);
  261. }
  262. foreach($contact["profile"] as $profile)
  263. {
  264. $connectFields = array(
  265. 'CONTACT_ID' => $contactId,
  266. 'CONTACT_PROFILE_ID' => $profile['PROFILE_ID'],
  267. 'CONTACT_PORTAL' => $profile['PORTAL'],
  268. 'CONNECT_TYPE' => $profile['TYPE'],
  269. 'LAST_AUTHORIZE' => DateTime::createFromUserTime(\CRestUtil::unConvertDateTime($profile['LAST_AUTHORIZE'])),
  270. );
  271. $r = ContactConnectTable::add($connectFields);
  272. if($r->isSuccess())
  273. {
  274. if(!isset($contactFields["CONNECT"]))
  275. {
  276. $contactFields["CONNECT"] = array($connectFields);
  277. }
  278. else
  279. {
  280. $contactFields["CONNECT"][] = $connectFields;
  281. }
  282. }
  283. }
  284. if(!isset($existedContacts[$contactFields["CONTACT_XML_ID"]]))
  285. {
  286. static::notifyJoin($contactId, $contactFields);
  287. }
  288. }
  289. }
  290. static::notifyJoinFinish($owner["USER_ID"]);
  291. }
  292. protected static function processPossibleContacts($owner, array $contactsList)
  293. {
  294. if(!Main\Loader::includeModule('rest'))
  295. {
  296. return;
  297. }
  298. $existedContacts = array();
  299. $dbRes = UserLinkTable::getList(array(
  300. 'filter' => array(
  301. '=SOCSERV_USER_ID' => $owner["ID"],
  302. '=SOCSERV_USER.EXTERNAL_AUTH_ID' => \CSocServBitrix24Net::ID,
  303. ),
  304. 'select' => array('ID', 'LINK_UID')
  305. ));
  306. while($existedContact = $dbRes->fetch())
  307. {
  308. $existedContacts[$existedContact['LINK_UID']] = $existedContact['ID'];
  309. }
  310. foreach($contactsList as $contact)
  311. {
  312. $contactFields = array(
  313. "USER_ID" => $owner["USER_ID"],
  314. "SOCSERV_USER_ID" => $owner["ID"],
  315. "LINK_UID" => $contact["CONTACT_ID"],
  316. "LINK_NAME" => $contact["NAME"],
  317. "LINK_LAST_NAME" => $contact["LAST_NAME"],
  318. "LINK_PICTURE" => $contact["PHOTO"],
  319. );
  320. $linkId = false;
  321. if(isset($existedContacts[$contactFields["LINK_UID"]]))
  322. {
  323. $linkId = $existedContacts[$contactFields["LINK_UID"]];
  324. UserLinkTable::update($linkId, $contactFields);
  325. }
  326. else
  327. {
  328. $result = UserLinkTable::add($contactFields);
  329. if($result->isSuccess())
  330. {
  331. $linkId = $result->getId();
  332. }
  333. }
  334. if(
  335. $linkId !== false
  336. && isset($contact["profile"])
  337. && count($contact["profile"]) > 0
  338. )
  339. {
  340. if(isset($existedContacts[$contactFields["LINK_UID"]]))
  341. {
  342. ContactConnectTable::deleteByLink($linkId);
  343. }
  344. foreach($contact["profile"] as $profile)
  345. {
  346. $result = ContactConnectTable::add(array(
  347. 'LINK_ID' => $linkId,
  348. 'CONTACT_PROFILE_ID' => $profile['PROFILE_ID'],
  349. 'CONTACT_PORTAL' => $profile['PORTAL'],
  350. 'CONNECT_TYPE' => $profile['TYPE'],
  351. 'LAST_AUTHORIZE' => DateTime::createFromUserTime(\CRestUtil::unConvertDateTime($profile['LAST_AUTHORIZE'])),
  352. ));
  353. }
  354. }
  355. }
  356. }
  357. public static function getConnectId($connect)
  358. {
  359. return $connect["CONNECT_TYPE"].$connect["CONTACT_PROFILE_ID"];
  360. }
  361. protected static function notifyJoin($contactId, array $contactInfo = null)
  362. {
  363. $network = new Network();
  364. if($network->isOptionEnabled() && Main\Loader::includeModule('im'))
  365. {
  366. if($contactInfo === null)
  367. {
  368. $dbRes = static::getByPrimary($contactId);
  369. $contactInfo = $dbRes->fetch();
  370. }
  371. if(!$contactInfo)
  372. {
  373. return false;
  374. }
  375. if(!isset($contactInfo["CONNECT"]))
  376. {
  377. $contactInfo["CONNECT"] = array();
  378. $dbRes = ContactConnectTable::getList(array(
  379. "order" => array("LAST_AUTHORIZE" => "ASC"),
  380. "filter" => array(
  381. "=CONTACT_ID" => $contactInfo["ID"],
  382. ),
  383. "limit" => 1,
  384. "select" => array(
  385. "CONTACT_PROFILE_ID", "CONNECT_TYPE"
  386. )
  387. ));
  388. while($connect = $dbRes->fetch())
  389. {
  390. $contactInfo["CONNECT"][] = $connect;
  391. }
  392. }
  393. if(count($contactInfo["CONNECT"]) > 0)
  394. {
  395. if(isset($contactInfo["CONTACT_PHOTO_RESIZED"]))
  396. {
  397. $contactInfo["CONTACT_PHOTO"] = $contactInfo["CONTACT_PHOTO_RESIZED"];
  398. }
  399. if($contactInfo["NOTIFY"] == ContactTable::NOTIFY)
  400. {
  401. $attach = new \CIMMessageParamAttach(null, \CIMMessageParamAttach::NORMAL);
  402. $attachParams = array(
  403. "NAME" => \CUser::FormatName(\CSite::GetNameFormat(), array(
  404. "NAME" => $contactInfo["CONTACT_NAME"],
  405. "LAST_NAME" => $contactInfo["CONTACT_LAST_NAME"]
  406. ), false, false),
  407. );
  408. if($contactInfo["CONTACT_PHOTO"])
  409. {
  410. $attachParams["AVATAR"] = $contactInfo["CONTACT_PHOTO"];
  411. }
  412. $attachParams["NETWORK_ID"] = static::getConnectId($contactInfo["CONNECT"][0]);
  413. $attach->AddUser($attachParams);
  414. $messageFields = array(
  415. "TO_USER_ID" => $contactInfo["USER_ID"],
  416. "FROM_USER_ID" => 0,
  417. "NOTIFY_TYPE" => IM_NOTIFY_SYSTEM,
  418. "NOTIFY_MODULE" => "socialservices",
  419. "NOTIFY_EVENT" => "contacts",
  420. "NOTIFY_MESSAGE" => Loc::getMessage("SS_JOIN_NOTIFY"),
  421. "NOTIFY_MESSAGE_OUT" => IM_MAIL_SKIP,
  422. "ATTACH" => array($attach),
  423. );
  424. return \CIMNotify::Add($messageFields);
  425. }
  426. else
  427. {
  428. static::$notifyStack[] = $contactInfo;
  429. }
  430. }
  431. }
  432. return false;
  433. }
  434. protected static function notifyJoinFinish($userId)
  435. {
  436. $network = new Network();
  437. if(
  438. $network->isOptionEnabled()
  439. && count(static::$notifyStack) > 0
  440. && Main\Loader::includeModule('im')
  441. )
  442. {
  443. $attach = new \CIMMessageParamAttach(null, \CIMMessageParamAttach::NORMAL);
  444. $count = 0;
  445. foreach(static::$notifyStack as $contactInfo)
  446. {
  447. if(++$count > static::NOTIFY_CONTACT_COUNT)
  448. {
  449. $attach->AddHtml('<a href="'.str_replace("#USER_ID#", $userId, Option::get("intranet", "path_user", "/company/persona/user/#USER_ID#/")).'">'.Loc::getMessage("SS_JOIN_NOTIFY_MORE", array("#NUM#" => count(static::$notifyStack)-$count+1)).'</a>');
  450. break;
  451. }
  452. else
  453. {
  454. $attachParams = array(
  455. "NAME" => \CUser::FormatName(\CSite::GetNameFormat(), array(
  456. "NAME" => $contactInfo["CONTACT_NAME"],
  457. "LAST_NAME" => $contactInfo["CONTACT_LAST_NAME"]
  458. ), false, false),
  459. );
  460. if($contactInfo["CONTACT_PHOTO"])
  461. {
  462. $attachParams["AVATAR"] = $contactInfo["CONTACT_PHOTO"];
  463. }
  464. $attachParams["NETWORK_ID"] = static::getConnectId($contactInfo["CONNECT"][0]);
  465. $attach->AddUser($attachParams);
  466. }
  467. }
  468. $messageFields = array(
  469. "TO_USER_ID" => $userId,
  470. "FROM_USER_ID" => 0,
  471. "NOTIFY_TYPE" => IM_NOTIFY_SYSTEM,
  472. "NOTIFY_MODULE" => "socialservices",
  473. "NOTIFY_EVENT" => "multiple_contacts",
  474. "NOTIFY_MESSAGE" => Loc::getMessage("SS_JOIN_NOTIFY_MULTIPLE"),
  475. "NOTIFY_MESSAGE_OUT" => IM_MAIL_SKIP,
  476. "ATTACH" => array($attach),
  477. );
  478. \CIMNotify::Add($messageFields);
  479. static::$notifyStack = array();
  480. }
  481. }
  482. /**
  483. * @deprecated
  484. */
  485. protected static function notifyPossible($userId)
  486. {
  487. $network = new Network();
  488. if($network->isOptionEnabled() && Main\Loader::includeModule('im'))
  489. {
  490. $ts = time();
  491. $alreadyShown = \CUserOptions::GetOption("socialservices", "possible_contacts", null, $userId);
  492. if(
  493. !is_array($alreadyShown)
  494. || $alreadyShown[static::POSSIBLE_RESET_TIME_KEY] < $ts - static::POSSIBLE_RESET_TIME
  495. )
  496. {
  497. $alreadyShown = array();
  498. }
  499. else
  500. {
  501. $ts = $alreadyShown[static::POSSIBLE_RESET_TIME_KEY];
  502. unset($alreadyShown[static::POSSIBLE_RESET_TIME_KEY]);
  503. }
  504. $dateLimit = new DateTime();
  505. $dateLimit->add(static::POSSIBLE_LAST_AUTHORIZE_LIMIT);
  506. $contactList = ContactConnectTable::getList(array(
  507. 'order' => array('LAST_AUTHORIZE' => 'DESC'),
  508. 'filter' => array(
  509. '!=LINK_ID' => '',
  510. '=CONNECT_TYPE' => ContactConnectTable::TYPE_PORTAL,
  511. '>=LAST_AUTHORIZE' => $dateLimit,
  512. '=LINK.USER_ID' => $userId,
  513. '!=LINK.ID' => $alreadyShown,
  514. ),
  515. 'count_total' => true,
  516. 'group' => array('LINK_ID'),
  517. 'limit' => static::NOTIFY_POSSIBLE_COUNT,
  518. 'select' => array(
  519. 'LINK_ID', 'LINK_NAME' => 'LINK.LINK_NAME', 'LINK_LAST_NAME' => 'LINK.LINK_LAST_NAME', 'LINK_PICTURE' => 'LINK.LINK_PICTURE',
  520. ),
  521. ));
  522. /*
  523. $contactList = UserLinkTable::getList(array(
  524. 'order' => array("RND" => "ASC"),
  525. 'filter' => array(
  526. '=USER_ID' => $userId,
  527. '!=ID' => $alreadyShown,
  528. ),
  529. 'limit' => static::NOTIFY_POSSIBLE_COUNT,
  530. 'count_total' => true,
  531. 'group' => array("CONNECT.CONTACT_ID"), // Mistake? CONNECT.LINK_ID should be here
  532. 'runtime' => array(
  533. new Entity\ExpressionField('RND', 'RAND()'),
  534. new Entity\ReferenceField(
  535. "CONNECT",
  536. ContactConnectTable::getEntity(),
  537. array(
  538. "=ref.LINK_ID" => "this.ID",
  539. "=ref.CONNECT_TYPE" => new Main\DB\SqlExpression(
  540. '?', ContactConnectTable::TYPE_PORTAL
  541. )
  542. ),
  543. array("join_type"=>"inner")
  544. ),
  545. )
  546. ));
  547. */
  548. $count = $contactList->getCount();
  549. if($count > 0)
  550. {
  551. $attach = new \CIMMessageParamAttach(null, \CIMMessageParamAttach::NORMAL);
  552. while($contactInfo = $contactList->fetch())
  553. {
  554. $alreadyShown[] = $contactInfo["LINK_ID"];
  555. // get all link portals, authorized during last week
  556. $contactInfo["CONNECT"] = array();
  557. $dbRes = ContactConnectTable::getList(array(
  558. "order" => array("LAST_AUTHORIZE" => "DESC"),
  559. "filter" => array(
  560. "=LINK_ID" => $contactInfo["LINK_ID"],
  561. ">=LAST_AUTHORIZE" => $dateLimit,
  562. ),
  563. "limit" => 1,
  564. "select" => array(
  565. "CONTACT_PROFILE_ID", "CONNECT_TYPE"
  566. )
  567. ));
  568. while($connect = $dbRes->fetch())
  569. {
  570. $contactInfo["CONNECT"][] = $connect;
  571. }
  572. if(count($contactInfo["CONNECT"]) > 0)
  573. {
  574. $attachParams = array(
  575. "NAME" => \CUser::FormatName(\CSite::GetNameFormat(), array(
  576. "NAME" => $contactInfo["LINK_NAME"],
  577. "LAST_NAME" => $contactInfo["LINK_LAST_NAME"]
  578. ), false, false),
  579. );
  580. if($contactInfo["LINK_PICTURE"])
  581. {
  582. $attachParams["AVATAR"] = $contactInfo["LINK_PICTURE"];
  583. }
  584. $attachParams["NETWORK_ID"] = static::getConnectId($contactInfo["CONNECT"][0]);
  585. $attach->AddUser($attachParams);
  586. }
  587. }
  588. /*
  589. if($count > static::NOTIFY_POSSIBLE_COUNT)
  590. {
  591. $attach->AddHtml('<a href="'.str_replace("#USER_ID#", $userId, Option::get("intranet", "path_user", "/company/persona/user/#USER_ID#/")).'">'.Loc::getMessage("SS_JOIN_NOTIFY_MORE", array("#NUM#" => $count - static::NOTIFY_POSSIBLE_COUNT)).'</a>');
  592. }
  593. */
  594. $messageFields = array(
  595. "TO_USER_ID" => $userId,
  596. "FROM_USER_ID" => 0,
  597. "NOTIFY_TYPE" => IM_NOTIFY_SYSTEM,
  598. "NOTIFY_MODULE" => "socialservices",
  599. "NOTIFY_EVENT" => "possible_contacts",
  600. "NOTIFY_MESSAGE" => Loc::getMessage("SS_JOIN_NOTIFY_POSSIBLE"),
  601. "NOTIFY_MESSAGE_OUT" => IM_MAIL_SKIP,
  602. "ATTACH" => $attach,
  603. );
  604. \CIMNotify::Add($messageFields);
  605. }
  606. $alreadyShown[static::POSSIBLE_RESET_TIME_KEY] = $ts;
  607. \CUserOptions::SetOption("socialservices", "possible_contacts", $alreadyShown, false, $userId);
  608. }
  609. }
  610. }