1C-Bitrix 25.700.0
Загрузка...
Поиск...
Не найдено
GeneralChat.php
См. документацию.
1<?php
2
3namespace Bitrix\Im\V2\Chat;
4
5use Bitrix\Im\Model\ChatTable;
6use Bitrix\Im\Recent;
7use Bitrix\Im\V2\Chat;
8use Bitrix\Im\V2\Entity\User\User;
9use Bitrix\Im\V2\Relation;
10use Bitrix\Im\V2\Result;
11use Bitrix\Im\V2\Service\Context;
12use Bitrix\Intranet\Settings\CommunicationSettings;
13use Bitrix\Main\Application;
14use Bitrix\Main\Config\Option;
15use Bitrix\Main\Data\Cache;
16use Bitrix\Main\Loader;
17use Bitrix\Main\Localization\Loc;
18use Bitrix\Main\Type\DateTime;
19use CAllSite;
20
22{
23 public const GENERAL_MESSAGE_TYPE_JOIN = 'join';
24 public const GENERAL_MESSAGE_TYPE_LEAVE = 'leave';
25 public const ID_CACHE_ID = 'general_chat_id';
26 public const MANAGERS_CACHE_ID = 'general_chat_managers';
27 public const DISABLE_GENERAL_CHAT_OPTION = 'disable_general_chat';
28
29 private const MESSAGE_COMPONENT_START = 'GeneralChatCreationMessage';
30
31 protected static ?self $instance = null;
32 protected static bool $wasSearched = false;
33 protected static Result $resultFind;
34 protected static int $idStaticCache;
35
36 protected function getDefaultType(): string
37 {
38 return self::IM_TYPE_OPEN;
39 }
40
41 protected function getDefaultEntityType(): string
42 {
43 return self::ENTITY_TYPE_GENERAL;
44 }
45
46 public function hasManageMessagesAccess(?int $userId = null): bool
47 {
48 if ($this->getId() === null || $this->getId() === 0)
49 {
50 return false;
51 }
52
53 if ($this->getManageMessages() === Chat::MANAGE_RIGHTS_NONE)
54 {
55 return false;
56 }
57
58 $userId ??= $this->getContext()->getUserId();
59 if ($this->getManageMessages() === Chat::MANAGE_RIGHTS_MEMBER)
60 {
61 return true;
62 }
63
64 if ($this->getAuthorId() === $userId)
65 {
66 return true;
67 }
68
69 if ($this->getManageMessages() === Chat::MANAGE_RIGHTS_OWNER)
70 {
71 return false;
72 }
73
74 return in_array($userId, $this->getManagerList(), true);
75 }
76
77 public static function isEnable(): bool
78 {
79 return Option::get('im', self::DISABLE_GENERAL_CHAT_OPTION, 'N') === 'N';
80 }
81
82 public function getManagerList(bool $fullList = true): array
83 {
84 $cache = static::getCache(self::MANAGERS_CACHE_ID);
85
86 $cachedManagerList = $cache->getVars();
87
88 if ($cachedManagerList !== false)
89 {
90 return $cachedManagerList;
91 }
92
93 $managerList = $this->getRelationFacade()->getManagerOnly()->getUserIds();
94
95 $cache->startDataCache();
96 $cache->endDataCache($managerList);
97
98 return $managerList;
99 }
100
101 protected function changeManagers(array $userIds, bool $isManager, bool $sendPush = true): self
102 {
103 self::cleanGeneralChatCache(self::MANAGERS_CACHE_ID);
104
105 return parent::changeManagers($userIds, $isManager, $sendPush);
106 }
107
108 public static function get(): ?GeneralChat
109 {
110 if (self::$wasSearched)
111 {
112 return self::$instance;
113 }
114
115 $chatId = static::getGeneralChatId();
116 $chat = Chat::getInstance($chatId);
117 self::$instance = ($chat instanceof NullChat) ? null : $chat;
118 self::$wasSearched = true;
119
120 return self::$instance;
121 }
122
123 public static function getGeneralChatId(): ?int
124 {
125 if (!static::isEnable())
126 {
127 return 0;
128 }
129
130 if (isset(self::$idStaticCache))
131 {
132 return self::$idStaticCache;
133 }
134
135 $cache = static::getCache(self::ID_CACHE_ID);
136
137 $cachedId = $cache->getVars();
138
139 if ($cachedId !== false)
140 {
141 self::$idStaticCache = $cachedId ?? 0;
142
143 return self::$idStaticCache;
144 }
145
146 $result = ChatTable::query()
147 ->setSelect(['ID'])
148 ->where('TYPE', Chat::IM_TYPE_OPEN)
149 ->where('ENTITY_TYPE', Chat::ENTITY_TYPE_GENERAL)
150 ->fetch() ?: []
151 ;
152
153 self::$idStaticCache = $result['ID'] ?? 0;
154 $cache->startDataCache();
155 $cache->endDataCache(self::$idStaticCache);
156
157 return self::$idStaticCache;
158 }
159
160 public function setManagers(array $managerIds): Chat
161 {
162 static::cleanGeneralChatCache(self::MANAGERS_CACHE_ID);
163
164 return parent::setManagers($managerIds);
165 }
166
172 public static function find(array $params = [], ?Context $context = null): Result
173 {
174 if (isset(self::$resultFind))
175 {
176 return self::$resultFind;
177 }
178
179 $result = new Result;
180
181 $row = ChatTable::query()
182 ->setSelect(['ID', 'TYPE', 'ENTITY_TYPE', 'ENTITY_ID'])
183 ->where('ENTITY_TYPE', self::ENTITY_TYPE_GENERAL)
184 ->setLimit(1)
185 ->setOrder(['ID' => 'DESC'])
186 ->fetch()
187 ;
188
189 if ($row)
190 {
191 $result->setResult([
192 'ID' => (int)$row['ID'],
193 'TYPE' => $row['TYPE'],
194 'ENTITY_TYPE' => $row['ENTITY_TYPE'],
195 'ENTITY_ID' => $row['ENTITY_ID'],
196 ]);
197 }
198
199 self::$resultFind = $result;
200
201 return $result;
202 }
203
204 public function add(array $params, ?Context $context = null): Result
205 {
206 $result = new Result;
207
208 $generalChatResult = self::find();
209 if ($generalChatResult->hasResult())
210 {
211 $generalChat = new GeneralChat(['ID' => $generalChatResult->getResult()['ID']]);
212 return $result->setResult([
213 'CHAT_ID' => $generalChat->getChatId(),
214 'CHAT' => $generalChat,
215 ]);
216 }
217
218 $installUsers = $this->getUsersForInstall();
219
220 $portalLanguage = self::getPortalLanguage();
221
222 $params = [
223 'TYPE' => self::IM_TYPE_OPEN,
224 'ENTITY_TYPE' => self::ENTITY_TYPE_GENERAL,
225 'COLOR' => 'AZURE',
226 'TITLE' => Loc::getMessage('IM_CHAT_GENERAL_TITLE', null, $portalLanguage),
227 'DESCRIPTION' => Loc::getMessage('IM_CHAT_GENERAL_DESCRIPTION_MSGVER_1', null, $portalLanguage),
228 'AUTHOR_ID' => User::getFirstAdmin(),
229 'USER_COUNT' => count($installUsers),
230 ];
231
232 $chat = new static($params);
233 $chat->setExtranet(false);
234 $chat->save();
235
236 if (!$chat->getChatId())
237 {
238 return $result->addError(new ChatError(ChatError::CREATION_ERROR));
239 }
240
241 $adminIds = [];
242 if (Loader::includeModule('bitrix24'))
243 {
244 $adminIds = \CBitrix24::getAllAdminId();
245 }
246
247 foreach ($installUsers as $user)
248 {
249 $relation = new Relation();
250 $relation->setChatId($chat->getChatId());
251 $relation->setUserId((int)$user['ID']);
252 $relation->setManager(in_array((int)$user['ID'], $adminIds, true));
253 $relation->setMessageType(self::IM_TYPE_OPEN);
254 $relation->setStatus(IM_STATUS_READ);
255 $relation->save();
256 }
257
258 $chat->sendBanner();
259 $chat->addIndex();
260
261 self::linkGeneralChat($chat->getChatId());
262
263 $result->setResult([
264 'CHAT_ID' => $chat->getChatId(),
265 'CHAT' => $chat,
266 ]);
267
268 self::cleanGeneralChatCache(self::ID_CACHE_ID);
269 self::cleanGeneralChatCache(self::MANAGERS_CACHE_ID);
270 self::cleanCache($chat->getChatId());
271 $chat->isFilledNonCachedData = false;
272
273 return $result;
274 }
275
276 private static function getPortalLanguage(): ?string
277 {
278 $defSite = CAllSite::GetDefSite();
279 if ($defSite === false)
280 {
281 return null;
282 }
283
284 $portalData = CAllSite::GetByID($defSite)->Fetch();
285 if ($portalData)
286 {
287 $languageId = $portalData['LANGUAGE_ID'];
288 if ($languageId !== '')
289 {
290 return $languageId;
291 }
292 }
293
294 return null;
295 }
296
297 public static function linkGeneralChat(?int $chatId = null): bool
298 {
299 if (!$chatId)
300 {
301 $chatId = self::getGeneralChatId();
302 }
303
304 if (!$chatId)
305 {
306 return false;
307 }
308
309 if (Loader::includeModule('pull'))
310 {
311 \CPullStack::AddShared([
312 'module_id' => 'im',
313 'command' => 'generalChatId',
314 'params' => [
315 'id' => $chatId
316 ],
317 'extra' => \Bitrix\Im\Common::getPullExtra()
318 ]);
319 }
320
321 return true;
322 }
323
328 public static function cleanGeneralChatCache(string $cacheId): void
329 {
330 Application::getInstance()->getCache()->clean($cacheId, static::getCacheDir());
331 }
332
333 public static function unlinkGeneralChat(): bool
334 {
335 if (Loader::includeModule('pull'))
336 {
337 \CPullStack::AddShared([
338 'module_id' => 'im',
339 'command' => 'generalChatId',
340 'params' => [
341 'id' => 0
342 ],
343 'extra' => \Bitrix\Im\Common::getPullExtra()
344 ]);
345 }
346
347 static::cleanGeneralChatCache(self::ID_CACHE_ID);
348 static::cleanGeneralChatCache(self::MANAGERS_CACHE_ID);
349
350 return true;
351 }
352
353 public function canJoinGeneralChat(int $userId): bool
354 {
355 if (
356 $userId <= 0
357 || !self::getGeneralChatId()
358 || !Loader::includeModule('intranet')
359 )
360 {
361 return false;
362 }
363
365 $sql = "
366 SELECT DISTINCT U.ID
367 FROM
368 b_user U
369 INNER JOIN b_user_field F ON F.ENTITY_ID = 'USER' AND F.FIELD_NAME = 'UF_DEPARTMENT'
370 INNER JOIN b_utm_user UF ON
371 UF.FIELD_ID = F.ID
372 AND UF.VALUE_ID = U.ID
373 AND UF.VALUE_INT > 0
374 WHERE
375 U.ACTIVE = 'Y'
376 AND U.ID = " . $userId . "
377 AND F.ENTITY_ID = 'USER'
378 AND F.FIELD_NAME = 'UF_DEPARTMENT'
379 LIMIT 1
380 ";
381 if ($connection->query($sql)->fetch())
382 {
383 return true;
384 }
385
386 return false;
387 }
388
389 private function getUsersForInstall(): array
390 {
392 $types = implode("', '", $externalUserTypes);
393 if (Loader::includeModule('intranet'))
394 {
395 $sql = "
396 SELECT DISTINCT U.ID
397 FROM
398 b_user U
399 INNER JOIN b_user_field F ON F.ENTITY_ID = 'USER' AND F.FIELD_NAME = 'UF_DEPARTMENT'
400 INNER JOIN b_utm_user UF ON
401 UF.FIELD_ID = F.ID
402 AND UF.VALUE_ID = U.ID
403 AND UF.VALUE_INT > 0
404 WHERE
405 U.ACTIVE = 'Y'
406 AND (U.EXTERNAL_AUTH_ID IS NULL OR U.EXTERNAL_AUTH_ID NOT IN ('{$types}') )
407 AND F.ENTITY_ID = 'USER'
408 AND F.FIELD_NAME = 'UF_DEPARTMENT'
409 ";
410 }
411 else
412 {
413 $sql = "
414 SELECT ID
415 FROM b_user U
416 WHERE
417 U.ACTIVE = 'Y'
418 AND (U.EXTERNAL_AUTH_ID IS NULL OR U.EXTERNAL_AUTH_ID NOT IN ('{$types}') )
419 ";
420 }
421
423 return $connection->query($sql)->fetchAll();
424 }
425
426 protected function sendBanner(?int $authorId = null): void
427 {
429 'MESSAGE_TYPE' => self::IM_TYPE_CHAT,
430 'TO_CHAT_ID' => $this->getChatId(),
431 'FROM_USER_ID' => 0,
432 'MESSAGE' => Loc::getMessage('IM_CHAT_GENERAL_CREATE_WELCOME', null, self::getPortalLanguage()),
433 'SYSTEM' => 'Y',
434 'PUSH' => 'N',
435 'PARAMS' => [
436 'COMPONENT_ID' => self::MESSAGE_COMPONENT_START,
437 'NOTIFY' => 'N',
438 ],
439 'SKIP_COUNTER_INCREMENTS' => 'Y',
440 ]);
441 }
442
443 public static function getAutoMessageStatus(string $type): bool
444 {
445 switch ($type)
446 {
447 case self::GENERAL_MESSAGE_TYPE_JOIN:
448 return (bool)\COption::GetOptionString("im", "general_chat_message_join");
449 case self::GENERAL_MESSAGE_TYPE_LEAVE:
450 return (bool)\COption::GetOptionString("im", "general_chat_message_leave");
451 default:
452 return false;
453 }
454 }
455
457 {
458 $result['generalChatCanPostList'] = self::getCanPostList();
459 $result['generalChatCanPost'] = $this->getManageMessages();
460 $result['generalChatShowManagersList'] = self::MANAGE_RIGHTS_MANAGERS;
461 $managerIds = $this->getRelationFacade()->getManagerOnly()->getUserIds();
462 $managers = array_map(function ($managerId) {
463 return 'U' . $managerId;
464 }, $managerIds);
465 Loader::includeModule('intranet');
466 if (method_exists('\Bitrix\Intranet\Settings\CommunicationSettings', 'processOldAccessCodes'))
467 {
468 $result['generalChatManagersList'] = CommunicationSettings::processOldAccessCodes($managers);
469 }
470 else
471 {
472 $result['generalChatManagersList'] = \IntranetConfigsComponent::processOldAccessCodes($managers);
473 }
474
475 return $result;
476 }
477
478 protected function getAccessCodesForDiskFolder(): array
479 {
480 $accessCodes = parent::getAccessCodesForDiskFolder();
481 $departmentCode = \CIMDisk::GetTopDepartmentCode();
482
483 if ($departmentCode)
484 {
485 $driver = \Bitrix\Disk\Driver::getInstance();
486 $rightsManager = $driver->getRightsManager();
487 $accessCodes[] = [
488 'ACCESS_CODE' => $departmentCode,
489 'TASK_ID' => $rightsManager->getTaskIdByName($rightsManager::TASK_READ)
490 ];
491 }
492
493 return $accessCodes;
494 }
495
496 public static function deleteGeneralChat(): Result
497 {
498 $generalChat = self::get();
499 if (!$generalChat)
500 {
501 return (new Result())->addError(new ChatError(ChatError::NOT_FOUND));
502 }
503
504 return $generalChat->deleteChat();
505 }
506
507 protected function sendMessageUsersAdd(array $usersToAdd, Relation\AddUsersConfig $config): void
508 {
509 if ($this->getContext()->getUserId() > 0)
510 {
511 parent::sendMessageUsersAdd($usersToAdd, $config);
512
513 return;
514 }
515
516 if (!self::getAutoMessageStatus(self::GENERAL_MESSAGE_TYPE_JOIN))
517 {
518 return;
519 }
520
521 $userCodes = [];
522 foreach ($usersToAdd as $userId)
523 {
524 $userCodes[] = "[USER={$userId}][/USER]";
525 }
526 $userCodesString = implode(', ', $userCodes);
527
528 if (count($usersToAdd) > 1)
529 {
530 $messageText = Loc::getMessage("IM_CHAT_GENERAL_JOIN_PLURAL", ['#USER_NAME#' => $userCodesString]);
531 }
532 else
533 {
534 $user = User::getInstance(current($usersToAdd));
535 $genderModifier = $user->getGender() === 'F' ? '_F' : '';
536 $messageText = Loc::getMessage('IM_CHAT_GENERAL_JOIN' . $genderModifier, ['#USER_NAME#' => $userCodesString]);
537 }
538
539 \CIMChat::AddMessage([
540 "TO_CHAT_ID" => $this->getId(),
541 "MESSAGE" => $messageText,
542 "FROM_USER_ID" => $this->getContext(),
543 "SYSTEM" => 'Y',
544 "RECENT_ADD" => $config->skipRecent ? 'N' : 'Y',
545 "PARAMS" => [
546 "CODE" => 'CHAT_JOIN',
547 "NOTIFY" => $this->getEntityType() === self::ENTITY_TYPE_LINE? 'Y': 'N',
548 ],
549 "PUSH" => 'N',
550 "SKIP_USER_CHECK" => 'Y',
551 ]);
552 }
553
555 {
556 if (!self::getAutoMessageStatus(self::GENERAL_MESSAGE_TYPE_LEAVE))
557 {
558 return;
559 }
560
561 parent::sendMessageUserDelete($userId, $config);
562 }
563
564 public function getUserDeleteMessageText(int $deletedUserId): string
565 {
566 $user = User::getInstance($deletedUserId);
567
568 return Loc::getMessage(
569 "IM_CHAT_GENERAL_LEAVE_{$user->getGender()}",
570 ['#USER_NAME#' => htmlspecialcharsback($user->getName())]
571 );
572 }
573
574 public static function changeLangAgent(): string
575 {
576 if (!Loader::includeModule('im'))
577 {
578 return '';
579 }
580
581 GeneralChat::cleanGeneralChatCache(self::ID_CACHE_ID);
582
584 if ($chatId > 0)
585 {
586 $portalLanguage = self::getPortalLanguage();
587
588 ChatTable::update($chatId, [
589 'TITLE' => Loc::getMessage('IM_CHAT_GENERAL_TITLE', null, $portalLanguage),
590 'DESCRIPTION' => Loc::getMessage('IM_CHAT_GENERAL_DESCRIPTION_MSGVER_1', null, $portalLanguage),
591 ]);
592 }
593
594 return '';
595 }
596
597 protected function updateStateAfterRelationsAdd(array $usersToAdd): Chat
598 {
599 $result = parent::updateStateAfterRelationsAdd($usersToAdd);
600 Recent::raiseChat($this, $this->getRelationsByUserIds($usersToAdd), new DateTime());
601
602 return $result;
603 }
604
605 protected function disableUserDeleteMessage(bool $skipRecent = false): void
606 {
607 return;
608 }
609
610 private static function getCache(string $cacheId): Cache
611 {
612 $cache = Application::getInstance()->getCache();
613 $cacheTTL = 18144000;
614 $cacheDir = static::getCacheDir();
615 $cache->initCache($cacheTTL, $cacheId, $cacheDir);
616
617 return $cache;
618 }
619
620 private static function getCacheDir(): string
621 {
622 return '/bx/imc/general_chat';
623 }
624}
$connection
Определения actionsdefinitions.php:38
$type
Определения options.php:106
if(!is_object($USER)||! $USER->IsAuthorized()) $userId
Определения check_mail.php:18
static getPullExtra()
Определения common.php:127
static raiseChat(\Bitrix\Im\V2\Chat $chat, RelationCollection $relations, ?DateTime $lastActivity=null)
Определения recent.php:1582
const CREATION_ERROR
Определения ChatError.php:23
const NOT_FOUND
Определения ChatError.php:20
getRightsForIntranetConfig()
Определения GeneralChat.php:456
static self $instance
Определения GeneralChat.php:31
const MANAGERS_CACHE_ID
Определения GeneralChat.php:26
static cleanGeneralChatCache(string $cacheId)
Определения GeneralChat.php:328
sendMessageUsersAdd(array $usersToAdd, Relation\AddUsersConfig $config)
Определения GeneralChat.php:507
updateStateAfterRelationsAdd(array $usersToAdd)
Определения GeneralChat.php:597
add(array $params, ?Context $context=null)
Определения GeneralChat.php:204
hasManageMessagesAccess(?int $userId=null)
Определения GeneralChat.php:46
static changeLangAgent()
Определения GeneralChat.php:574
const GENERAL_MESSAGE_TYPE_JOIN
Определения GeneralChat.php:23
sendBanner(?int $authorId=null)
Определения GeneralChat.php:426
static getGeneralChatId()
Определения GeneralChat.php:123
getUserDeleteMessageText(int $deletedUserId)
Определения GeneralChat.php:564
static get()
Определения GeneralChat.php:108
static bool $wasSearched
Определения GeneralChat.php:32
changeManagers(array $userIds, bool $isManager, bool $sendPush=true)
Определения GeneralChat.php:101
static getAutoMessageStatus(string $type)
Определения GeneralChat.php:443
static find(array $params=[], ?Context $context=null)
Определения GeneralChat.php:172
getAccessCodesForDiskFolder()
Определения GeneralChat.php:478
const DISABLE_GENERAL_CHAT_OPTION
Определения GeneralChat.php:27
const GENERAL_MESSAGE_TYPE_LEAVE
Определения GeneralChat.php:24
sendMessageUserDelete(int $userId, Relation\DeleteUserConfig $config)
Определения GeneralChat.php:554
disableUserDeleteMessage(bool $skipRecent=false)
Определения GeneralChat.php:605
getManagerList(bool $fullList=true)
Определения GeneralChat.php:82
const ID_CACHE_ID
Определения GeneralChat.php:25
canJoinGeneralChat(int $userId)
Определения GeneralChat.php:353
setManagers(array $managerIds)
Определения GeneralChat.php:160
static isEnable()
Определения GeneralChat.php:77
static linkGeneralChat(?int $chatId=null)
Определения GeneralChat.php:297
static deleteGeneralChat()
Определения GeneralChat.php:496
static unlinkGeneralChat()
Определения GeneralChat.php:333
static Result $resultFind
Определения GeneralChat.php:33
static int $idStaticCache
Определения GeneralChat.php:34
static getFirstAdmin()
Определения User.php:717
static getInstance()
Определения application.php:98
static getConnection($name="")
Определения application.php:638
Определения result.php:20
fetch(\Bitrix\Main\Text\Converter $converter=null)
Определения result.php:179
static getInstance()
Определения servicelocator.php:33
static getExternalUserTypes()
Определения user.php:307
static GetTopDepartmentCode()
Определения im_disk.php:2502
static Add($arFields)
Определения im_message.php:28
getCache(string $moduleID)
Определения options.php:26
</td ></tr ></table ></td ></tr >< tr >< td class="bx-popup-label bx-width30"><?=GetMessage("PAGE_NEW_TAGS")?> array( $site)
Определения file_new.php:804
$result
Определения get_property_values.php:14
const IM_STATUS_READ
Определения include.php:42
$context
Определения csv_new_setup.php:223
htmlspecialcharsback($str)
Определения tools.php:2693
Определения culture.php:9
$user
Определения mysql_to_pgsql.php:33
$config
Определения quickway.php:69
</p ></td >< td valign=top style='border-top:none;border-left:none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;padding:0cm 2.0pt 0cm 2.0pt;height:9.0pt'>< p class=Normal align=center style='margin:0cm;margin-bottom:.0001pt;text-align:center;line-height:normal'>< a name=ТекстовоеПоле54 ></a ><?=($taxRate > count( $arTaxList) > 0) ? $taxRate."%"
Определения waybill.php:936
if($inWords) echo htmlspecialcharsbx(Number2Word_Rus(roundEx($totalVatSum $params['CURRENCY']
Определения template.php:799