Bitrix-D7 23.9
 
Загрузка...
Поиск...
Не найдено
GeneralChat.php
1<?php
2
3namespace Bitrix\Im\V2\Chat;
4
11use Bitrix\Intranet\Settings\CommunicationSettings;
17
19{
20 public const GENERAL_MESSAGE_TYPE_JOIN = 'join';
21 public const GENERAL_MESSAGE_TYPE_LEAVE = 'leave';
22 public const ID_CACHE_ID = 'general_chat_id';
23 public const MANAGERS_CACHE_ID = 'general_chat_managers';
24 public const DISABLE_GENERAL_CHAT_OPTION = 'disable_general_chat';
25
26 protected static ?self $instance = null;
27 protected static bool $wasSearched = false;
28 protected static Result $resultFind;
29
30 protected function getDefaultType(): string
31 {
32 return self::IM_TYPE_OPEN;
33 }
34
35 protected function getDefaultEntityType(): string
36 {
37 return self::ENTITY_TYPE_GENERAL;
38 }
39
40 public function hasPostAccess(?int $userId = null): bool
41 {
42 if ($this->getId() === null || $this->getId() === 0)
43 {
44 return false;
45 }
46
47 if ($this->getCanPost() === Chat::MANAGE_RIGHTS_NONE)
48 {
49 return false;
50 }
51
52 $userId ??= $this->getContext()->getUserId();
53 if ($this->getCanPost() === Chat::MANAGE_RIGHTS_MEMBER)
54 {
55 return true;
56 }
57
58 if ($this->getAuthorId() === $userId)
59 {
60 return true;
61 }
62
63 if ($this->getCanPost() === Chat::MANAGE_RIGHTS_OWNER)
64 {
65 return false;
66 }
67
68 return in_array($userId, $this->getManagerList(), true);
69 }
70
71 public static function isEnable(): bool
72 {
73 return Option::get('im', self::DISABLE_GENERAL_CHAT_OPTION, 'N') === 'N';
74 }
75
76 public function getManagerList(): array
77 {
78 $cache = static::getCache(self::MANAGERS_CACHE_ID);
79
80 $cachedManagerList = $cache->getVars();
81
82 if ($cachedManagerList !== false)
83 {
84 return $cachedManagerList;
85 }
86
87 $managerList = $this->getRelations(['FILTER' => ['MANAGER' => 'Y']])->getUserIds();
88
89 $cache->startDataCache();
90 $cache->endDataCache($managerList);
91
92 return $this->getRelations(['FILTER' => ['MANAGER' => 'Y']])->getUserIds();
93 }
94
95 public static function get(): ?GeneralChat
96 {
97 if (self::$wasSearched)
98 {
99 return self::$instance;
100 }
101
102 $chatId = static::getGeneralChatId();
103 $chat = Chat::getInstance($chatId);
104 self::$instance = ($chat instanceof NullChat) ? null : $chat;
105 self::$wasSearched = true;
106
107 return self::$instance;
108 }
109
110 public static function getGeneralChatId(): ?int
111 {
112 if (!static::isEnable())
113 {
114 return 0;
115 }
116
117 $cache = static::getCache(self::ID_CACHE_ID);
118
119 $cachedId = $cache->getVars();
120
121 if ($cachedId !== false)
122 {
123 return $cachedId ?? 0;
124 }
125
126 $result = ChatTable::query()
127 ->setSelect(['ID'])
128 ->where('TYPE', Chat::IM_TYPE_OPEN)
129 ->where('ENTITY_TYPE', Chat::ENTITY_TYPE_GENERAL)
130 ->fetch() ?: []
131 ;
132
133 $chatId = $result['ID'] ?? null;
134 $cache->startDataCache();
135 $cache->endDataCache($chatId);
136
137 return $chatId ?? 0;
138 }
139
140 public function setManagers(array $managerIds): Chat
141 {
142 static::cleanGeneralChatCache(self::MANAGERS_CACHE_ID);
143
144 return parent::setManagers($managerIds);
145 }
146
152 public static function find(array $params = [], ?Context $context = null): Result
153 {
154 if (isset(self::$resultFind))
155 {
156 return self::$resultFind;
157 }
158
159 $result = new Result;
160
161 $row = ChatTable::query()
162 ->setSelect(['ID', 'TYPE', 'ENTITY_TYPE', 'ENTITY_ID'])
163 ->where('ENTITY_TYPE', self::ENTITY_TYPE_GENERAL)
164 ->setLimit(1)
165 ->setOrder(['ID' => 'DESC'])
166 ->fetch()
167 ;
168
169 if ($row)
170 {
171 $result->setResult([
172 'ID' => (int)$row['ID'],
173 'TYPE' => $row['TYPE'],
174 'ENTITY_TYPE' => $row['ENTITY_TYPE'],
175 'ENTITY_ID' => $row['ENTITY_ID'],
176 ]);
177 }
178
179 self::$resultFind = $result;
180
181 return $result;
182 }
183
184 public function add(array $params, ?Context $context = null): Result
185 {
186 $result = new Result;
187
188 $generalChatResult = self::find();
189 if ($generalChatResult->hasResult())
190 {
191 $generalChat = new GeneralChat(['ID' => $generalChatResult->getResult()['ID']]);
192 return $result->setResult([
193 'CHAT_ID' => $generalChat->getChatId(),
194 'CHAT' => $generalChat,
195 ]);
196 }
197
198 $installUsers = $this->getUsersForInstall();
199
200 $params = [
201 'TYPE' => self::IM_TYPE_OPEN,
202 'ENTITY_TYPE' => self::ENTITY_TYPE_GENERAL,
203 'COLOR' => 'AZURE',
204 'TITLE' => Loc::getMessage('IM_CHAT_GENERAL_TITLE'),
205 'DESCRIPTION' => Loc::getMessage('IM_CHAT_GENERAL_DESCRIPTION'),
206 'AUTHOR_ID' => 0,
207 'USER_COUNT' => count($installUsers),
208 ];
209
210 $chat = new static($params);
211 $chat->setExtranet(false);
212 $chat->save();
213
214 if (!$chat->getChatId())
215 {
216 return $result->addError(new ChatError(ChatError::CREATION_ERROR));
217 }
218
219 $chat->sendBanner();
220
221 $adminIds = [];
222 if (Loader::includeModule('bitrix24'))
223 {
224 $adminIds = \CBitrix24::getAllAdminId();
225 }
226
227 foreach ($installUsers as $user)
228 {
229 $relation = new Relation();
230 $relation->setChatId($chat->getChatId());
231 $relation->setUserId((int)$user['ID']);
232 $relation->setManager(in_array((int)$user['ID'], $adminIds, true));
233 $relation->setMessageType(self::IM_TYPE_OPEN);
234 $relation->setStatus(IM_STATUS_READ);
235 $relation->save();
236 }
237
238 $chat->addIndex();
239
240 self::linkGeneralChat($chat->getChatId());
241
242 $result->setResult([
243 'CHAT_ID' => $chat->getChatId(),
244 'CHAT' => $chat,
245 ]);
246
247 self::cleanGeneralChatCache(self::ID_CACHE_ID);
248 self::cleanGeneralChatCache(self::MANAGERS_CACHE_ID);
249 self::cleanCache($chat->getChatId());
250
251 return $result;
252 }
253
254 public static function linkGeneralChat(?int $chatId = null): bool
255 {
256 if (!$chatId)
257 {
258 $chatId = self::getGeneralChatId();
259 }
260
261 if (!$chatId)
262 {
263 return false;
264 }
265
266 if (Loader::includeModule('pull'))
267 {
268 \CPullStack::AddShared([
269 'module_id' => 'im',
270 'command' => 'generalChatId',
271 'params' => [
272 'id' => $chatId
273 ],
274 'extra' => \Bitrix\Im\Common::getPullExtra()
275 ]);
276 }
277
278 return true;
279 }
280
285 public static function cleanGeneralChatCache(string $cacheId): void
286 {
287 Application::getInstance()->getCache()->clean($cacheId, static::getCacheDir());
288 }
289
290 public static function unlinkGeneralChat(): bool
291 {
292 if (Loader::includeModule('pull'))
293 {
294 \CPullStack::AddShared([
295 'module_id' => 'im',
296 'command' => 'generalChatId',
297 'params' => [
298 'id' => 0
299 ],
300 'extra' => \Bitrix\Im\Common::getPullExtra()
301 ]);
302 }
303
304 static::cleanGeneralChatCache(self::ID_CACHE_ID);
305 static::cleanGeneralChatCache(self::MANAGERS_CACHE_ID);
306
307 return true;
308 }
309
310 public function canJoinGeneralChat(int $userId): bool
311 {
312 if (
313 $userId <= 0
314 || !self::getGeneralChatId()
315 || !Loader::includeModule('intranet')
316 )
317 {
318 return false;
319 }
320
321 $connection = \Bitrix\Main\Application::getConnection();
322 $sql = "
323 SELECT DISTINCT U.ID
324 FROM
325 b_user U
326 INNER JOIN b_user_field F ON F.ENTITY_ID = 'USER' AND F.FIELD_NAME = 'UF_DEPARTMENT'
327 INNER JOIN b_utm_user UF ON
328 UF.FIELD_ID = F.ID
329 AND UF.VALUE_ID = U.ID
330 AND UF.VALUE_INT > 0
331 WHERE
332 U.ACTIVE = 'Y'
333 AND U.ID = " . $userId . "
334 AND F.ENTITY_ID = 'USER'
335 AND F.FIELD_NAME = 'UF_DEPARTMENT'
336 LIMIT 1
337 ";
338 if ($connection->query($sql)->fetch())
339 {
340 return true;
341 }
342
343 return false;
344 }
345
346 private function getUsersForInstall(): array
347 {
348 $externalUserTypes = \Bitrix\Main\UserTable::getExternalUserTypes();
349 $types = implode("', '", $externalUserTypes);
350 if (Loader::includeModule('intranet'))
351 {
352 $sql = "
353 SELECT DISTINCT U.ID
354 FROM
355 b_user U
356 INNER JOIN b_user_field F ON F.ENTITY_ID = 'USER' AND F.FIELD_NAME = 'UF_DEPARTMENT'
357 INNER JOIN b_utm_user UF ON
358 UF.FIELD_ID = F.ID
359 AND UF.VALUE_ID = U.ID
360 AND UF.VALUE_INT > 0
361 WHERE
362 U.ACTIVE = 'Y'
363 AND (U.EXTERNAL_AUTH_ID IS NULL OR U.EXTERNAL_AUTH_ID NOT IN ('{$types}') )
364 AND F.ENTITY_ID = 'USER'
365 AND F.FIELD_NAME = 'UF_DEPARTMENT'
366 ";
367 }
368 else
369 {
370 $sql = "
371 SELECT ID
372 FROM b_user U
373 WHERE
374 U.ACTIVE = 'Y'
375 AND (U.EXTERNAL_AUTH_ID IS NULL OR U.EXTERNAL_AUTH_ID NOT IN ('{$types}') )
376 ";
377 }
378
379 $connection = \Bitrix\Main\Application::getConnection();
380 return $connection->query($sql)->fetchAll();
381 }
382
383 protected function sendBanner(?int $authorId = null): void
384 {
385 \CIMMessage::Add([
386 'MESSAGE_TYPE' => self::IM_TYPE_CHAT,
387 'TO_CHAT_ID' => $this->getChatId(),
388 'FROM_USER_ID' => 0,
389 'MESSAGE' => Loc::getMessage('IM_CHAT_GENERAL_DESCRIPTION'),
390 'SYSTEM' => 'Y',
391 'PUSH' => 'N',
392 'PARAMS' => [
393 'COMPONENT_ID' => 'ChatCreationMessage',
394 ]
395 ]);
396 }
397
398 public static function getAutoMessageStatus(string $type): bool
399 {
400 switch ($type)
401 {
403 return (bool)\COption::GetOptionString("im", "general_chat_message_join");
405 return (bool)\COption::GetOptionString("im", "general_chat_message_leave");
406 default:
407 return false;
408 }
409 }
410
411 public function getRightsForIntranetConfig(): array
412 {
413 $result['generalChatCanPostList'] = self::getCanPostList();
414 $result['generalChatCanPost'] = $this->getCanPost();
415 $result['generalChatShowManagersList'] = self::MANAGE_RIGHTS_MANAGERS;
416 $managerIds = $this->getRelations([
417 'FILTER' => [
418 'MANAGER' => 'Y'
419 ]
420 ])->getUserIds();
421 $managers = array_map(function ($managerId) {
422 return 'U' . $managerId;
423 }, $managerIds);
424 Loader::includeModule('intranet');
425 if (method_exists('\Bitrix\Intranet\Settings\CommunicationSettings', 'processOldAccessCodes'))
426 {
427 $result['generalChatManagersList'] = CommunicationSettings::processOldAccessCodes($managers);
428 }
429 else
430 {
431 $result['generalChatManagersList'] = \IntranetConfigsComponent::processOldAccessCodes($managers);
432 }
433
434 return $result;
435 }
436
437 protected function getAccessCodesForDiskFolder(): array
438 {
439 $accessCodes = parent::getAccessCodesForDiskFolder();
440 $departmentCode = \CIMDisk::GetTopDepartmentCode();
441
442 if ($departmentCode)
443 {
444 $driver = \Bitrix\Disk\Driver::getInstance();
445 $rightsManager = $driver->getRightsManager();
446 $accessCodes[] = [
447 'ACCESS_CODE' => $departmentCode,
448 'TASK_ID' => $rightsManager->getTaskIdByName($rightsManager::TASK_READ)
449 ];
450 }
451
452 return $accessCodes;
453 }
454
455 public static function deleteGeneralChat(): Result
456 {
457 $generalChat = self::get();
458 if (!$generalChat)
459 {
460 return (new Result())->addError(new ChatError(ChatError::NOT_FOUND));
461 }
462
463 return $generalChat->deleteChat();
464 }
465
466 protected function sendMessageUsersAdd(array $usersToAdd, bool $skipRecent = false): void
467 {
468 if ($this->getContext()->getUserId() > 0)
469 {
470 parent::sendMessageUsersAdd($usersToAdd, $skipRecent);
471
472 return;
473 }
474
475 if (!self::getAutoMessageStatus(self::GENERAL_MESSAGE_TYPE_JOIN))
476 {
477 return;
478 }
479
480 $userCodes = [];
481 foreach ($usersToAdd as $userId)
482 {
483 $userCodes[] = "[USER={$userId}][/USER]";
484 }
485 $userCodesString = implode(', ', $userCodes);
486
487 if (count($usersToAdd) > 1)
488 {
489 $messageText = Loc::getMessage("IM_CHAT_GENERAL_JOIN_PLURAL", ['#USER_NAME#' => $userCodesString]);
490 }
491 else
492 {
493 $user = User::getInstance(current($usersToAdd));
494 $genderModifier = $user->getGender() === 'F' ? '_F' : '';
495 $messageText = Loc::getMessage('IM_CHAT_GENERAL_JOIN' . $genderModifier, ['#USER_NAME#' => $userCodesString]);
496 }
497
498 \CIMChat::AddMessage([
499 "TO_CHAT_ID" => $this->getId(),
500 "MESSAGE" => $messageText,
501 "FROM_USER_ID" => $this->getContext(),
502 "SYSTEM" => 'Y',
503 "RECENT_ADD" => $skipRecent ? 'N' : 'Y',
504 "PARAMS" => [
505 "CODE" => 'CHAT_JOIN',
506 "NOTIFY" => $this->getEntityType() === self::ENTITY_TYPE_LINE? 'Y': 'N',
507 ],
508 "PUSH" => 'N',
509 "SKIP_USER_CHECK" => 'Y',
510 ]);
511 }
512
513 protected function sendMessageUserDelete(int $userId, bool $skipRecent = false): void
514 {
515 if (!self::getAutoMessageStatus(self::GENERAL_MESSAGE_TYPE_LEAVE))
516 {
517 return;
518 }
519
520 parent::sendMessageUserDelete($userId, $skipRecent);
521 }
522
523 protected function getMessageUserDeleteText(int $userId): string
524 {
525 $user = User::getInstance($userId);
526
527 return Loc::getMessage("IM_CHAT_GENERAL_LEAVE_{$user->getGender()}", Array('#USER_NAME#' => htmlspecialcharsback($user->getName())));
528 }
529
530 private static function getCache(string $cacheId): Cache
531 {
532 $cache = Application::getInstance()->getCache();
533 $cacheTTL = 18144000;
534 $cacheDir = static::getCacheDir();
535 $cache->initCache($cacheTTL, $cacheId, $cacheDir);
536
537 return $cache;
538 }
539
540 private static function getCacheDir(): string
541 {
542 return '/bx/imc/general_chat';
543 }
544}
static getPullExtra()
Definition common.php:128
sendMessageUsersAdd(array $usersToAdd, bool $skipRecent=false)
static cleanGeneralChatCache(string $cacheId)
add(array $params, ?Context $context=null)
sendBanner(?int $authorId=null)
static getAutoMessageStatus(string $type)
static find(array $params=[], ?Context $context=null)
sendMessageUserDelete(int $userId, bool $skipRecent=false)
setManagers(array $managerIds)
hasPostAccess(?int $userId=null)
static linkGeneralChat(?int $chatId=null)
const MANAGE_RIGHTS_MEMBER
Definition Chat.php:133
const ENTITY_TYPE_GENERAL
Definition Chat.php:91
const IM_TYPE_OPEN
Definition Chat.php:61
const MANAGE_RIGHTS_NONE
Definition Chat.php:132
const MANAGE_RIGHTS_OWNER
Definition Chat.php:134
setResult($result)
Definition Result.php:17
static getMessage($code, $replace=null, $language=null)
Definition loc.php:29