1C-Bitrix 25.700.0
Загрузка...
Поиск...
Не найдено
chat.php
См. документацию.
1<?php
2
3namespace Bitrix\Im\Call\Integration;
4
5use Bitrix\Im\Call\Call;
6use Bitrix\Im\Call\CallUser;
7use Bitrix\Im\Common;
8use Bitrix\Im\Dialog;
9use Bitrix\Im\V2\Chat\NullChat;
10use Bitrix\Im\V2\Message;
11use Bitrix\Im\V2\Message\Params;
12use Bitrix\Main\Application;
13use Bitrix\Main\ArgumentException;
14use Bitrix\Main\Localization\Loc;
15use Bitrix\Main\UserTable;
16
17class Chat extends AbstractEntity
18{
19 protected $chatId;
21 protected $chatUsers = [];
22
23 const MUTE_MESSAGE = true;
24
25 public function __construct(Call $call, $entityId)
26 {
27 parent::__construct($call, $entityId);
28
29 if(Common::isChatId($entityId) || (int)$entityId > 0)
30 {
31 $chatId = \Bitrix\Im\Dialog::getChatId($entityId, $this->initiatorId);
32 }
33 else
34 {
35 throw new ArgumentException("Invalid chat id {$entityId}");
36 }
37
39
40 if (empty($userId))
41 {
42 $params['USER_ID'] = $this->initiatorId;
43 }
44
45 if (!$chat instanceof NullChat)
46 {
47 $this->chatFields = $this->getChatFields($chat);
48 }
49 $users = $chat->getRelationProvider()->getAllMemberIds();
50 $users[$call->getInitiatorId()] = $call->getInitiatorId();
51 if (!empty($users))
52 {
53 $activeRealUsers = UserTable::getList([
54 'select' => ['ID'],
55 'filter' => [
56 'ID' => $users,
57 '=ACTIVE' => 'Y',
58 [
59 'LOGIC' => 'OR',
60 '=IS_REAL_USER' => 'Y',
61 '=EXTERNAL_AUTH_ID' => \Bitrix\Im\Call\Auth::AUTH_TYPE,
62 ]
63 ]
64 ])->fetchAll();
65 $this->chatUsers = array_column($activeRealUsers, 'ID');
66 }
67 $this->chatId = $chatId;
68 }
69
75 public function getEntityType()
76 {
77 return EntityType::CHAT;
78 }
79
80 public function getEntityId($currentUserId = 0)
81 {
82 if($this->chatFields['message_type'] != IM_MESSAGE_PRIVATE || $currentUserId == 0)
83 {
84 return $this->entityId;
85 }
86
87 return $this->call->getInitiatorId() == $currentUserId ? $this->entityId : $this->call->getInitiatorId();
88 }
89
90 public function getChatId()
91 {
92 return $this->chatId;
93 }
94
100 public function getUsers()
101 {
102 return $this->chatUsers;
103 }
104
111 public function checkAccess(int $userId): bool
112 {
113 if (Common::isChatId($this->entityId))
114 {
115 return Dialog::hasAccess($this->entityId, $userId);
116 }
117
118 // one-to-one dialog
119 return ($userId === (int)$this->entityId || $userId === (int)$this->initiatorId);
120 }
121
128 public function canStartCall(int $userId): bool
129 {
130 if (Common::isChatId($this->entityId))
131 {
132 return Dialog::hasAccess($this->entityId, $userId);
133 }
134
135 if (
137 && \Bitrix\Main\Loader::includeModule('socialnetwork')
138 )
139 {
140 if (
142 && \CSocNetUser::IsFriendsAllowed()
143 && !\CSocNetUserRelations::IsFriends($this->entityId, $userId)
144 )
145 {
146 return false;
147 }
148
149 if (
151 && \CSocNetUser::IsFriendsAllowed()
152 && !\CSocNetUserRelations::IsFriends($this->entityId, $userId)
153 )
154 {
155 return false;
156 }
157 }
158
159 return true;
160 }
161
166 public function getOwnerId(): ?int
167 {
168 if (!empty($this->chatFields['owner']))
169 {
170 return (int)$this->chatFields['owner'];
171 }
172
173 return null;
174 }
175
180 public function getManagerIds(): array
181 {
182 if (!empty($this->chatFields['manager_list']))
183 {
184 return array_map('intVal', $this->chatFields['manager_list']);
185 }
186
187 return [];
188 }
189
196 public function getName($currentUserId)
197 {
198 if (!$this->chatFields)
199 {
200 return false;
201 }
202
203 if ($this->chatFields['message_type'] === IM_MESSAGE_PRIVATE && count($this->chatUsers) === 2)
204 {
205 return \Bitrix\Im\User::getInstance($this->getEntityId($currentUserId))->getFullName();
206 }
207 if ($this->chatFields['message_type'] !== IM_MESSAGE_PRIVATE)
208 {
209 return $this->chatFields['name'];
210 }
211
212 return false;
213 }
214
215 public function getAvatar($currentUserId)
216 {
217 if (!$this->chatFields)
218 {
219 return false;
220 }
221
222 if ($this->chatFields['message_type'] === IM_MESSAGE_PRIVATE && count($this->chatUsers) === 2)
223 {
224 return \Bitrix\Im\User::getInstance($this->getEntityId($currentUserId))->getAvatarHr();
225 }
226 if ($this->chatFields['message_type'] !== IM_MESSAGE_PRIVATE)
227 {
228 return $this->chatFields['avatar'];
229 }
230
231 return false;
232 }
233
234 public function getAvatarColor($currentUserId)
235 {
236 if (!$this->chatFields)
237 {
238 return false;
239 }
240
241 if ($this->chatFields['message_type'] === IM_MESSAGE_PRIVATE && count($this->chatUsers) === 2)
242 {
243 return \Bitrix\Im\User::getInstance($this->getEntityId($currentUserId))->getColor();
244 }
245 if ($this->chatFields['message_type'] !== IM_MESSAGE_PRIVATE)
246 {
247 return $this->chatFields['color'];
248 }
249
250 return false;
251 }
252
253 public function isPrivateChat(): bool
254 {
255 return $this->chatFields && $this->chatFields['message_type'] === IM_MESSAGE_PRIVATE;
256 }
257
258 public function onUserAdd($userId): bool
259 {
260 if (!$this->canExtendChat())
261 {
262 return false;
263 }
264 if ($this->chatFields['message_type'] == IM_MESSAGE_PRIVATE)
265 {
266 $chat = new \CIMChat();
267
268 $users = $this->chatUsers;
269 $users[] = $userId;
270
271 $chatId = $chat->add(['USERS' => $users]);
272 if (!$chatId)
273 {
274 return false;
275 }
276
277 if ($this->call)
278 {
279 $this->call->setAssociatedEntity(static::getEntityType(), 'chat'.$chatId);
280 // todo: remove when the calls are supported in the mobile
281 if ($this->call->getAssociatedEntity())
282 {
283 $this->call->getAssociatedEntity()->onCallCreate();
284 }
285 }
286 }
287 else
288 {
289 $chat = new \CIMChat();
291 $chat->addUser($chatId, $userId);
292 }
293
294 return true;
295 }
296
297 public function onExistingUsersInvite($userIds): bool
298 {
299 if (isset($this->chatFields['message_type']) && $this->chatFields['message_type'] === IM_MESSAGE_PRIVATE)
300 {
301 return true;
302 }
303
304 if (!$this->canExtendChat())
305 {
306 return false;
307 }
308
309 $chat = new \CIMChat();
311
312 return $chat->addUser($chatId, $userIds);
313 }
314
315 public function onStateChange($state, $prevState)
316 {
317 $initiatorId = $this->call->getInitiatorId();
318 //$initiator = \Bitrix\Im\User::getInstance($initiatorId);
319 if ($state === Call::STATE_INVITING && $prevState === Call::STATE_NEW)
320 {
321 // todo: return the call method when the calls are supported in the mobile
322 //$this->sendMessagesCallStart();
323 }
324 elseif ($state === Call::STATE_FINISHED)
325 {
326 $message = Loc::getMessage("IM_CALL_INTEGRATION_CHAT_CALL_FINISHED_V2", [
327 '#CALL_DURATION#' => $this->getCallDuration(),
328 ]);
329 $mute = true;
330 $skipCounterInc = true;
331
332 $userIds = array_values(array_filter($this->call->getUsers(), function($userId) use ($initiatorId)
333 {
334 return $userId != $initiatorId;
335 }));
336
338 'MESSAGE_TYPE' => 'FINISH',
339 'CALL_ID' => $this->call->getId(),
340 'INITIATOR_ID' => $this->call->getActionUserId(),
341 ];
342
343 if ($this->call instanceof \Bitrix\Call\Call\PlainCall)
344 {
345 $otherUser = \Bitrix\Im\User::getInstance($userIds[0]);
346 $otherUserState = $this->call->getUser($userIds[0]) ? $this->call->getUser($userIds[0])->getState() : '';
347
348 if ($otherUserState == CallUser::STATE_DECLINED)
349 {
350 $componentParams['MESSAGE_TYPE'] = 'DECLINED';
351 $message = Loc::getMessage("IM_CALL_INTEGRATION_CHAT_CALL_USER_DECLINED_V2_" . $otherUser->getGender(), [
352 '#NAME#' => $otherUser->getFullName(false)
353 ]);
354 }
355 elseif ($otherUserState == CallUser::STATE_BUSY)
356 {
357 $componentParams['MESSAGE_TYPE'] = 'BUSY';
358 $message = Loc::getMessage("IM_CALL_INTEGRATION_CHAT_CALL_USER_BUSY_" . $otherUser->getGender(), [
359 '#NAME#' => $otherUser->getFullName(false)
360 ]);
361 $mute = false;
362 $skipCounterInc = false;
363 }
364 elseif ($otherUserState == CallUser::STATE_UNAVAILABLE || $otherUserState == CallUser::STATE_CALLING)
365 {
366 $componentParams['MESSAGE_TYPE'] = 'MISSED';
367 $message = Loc::getMessage("IM_CALL_INTEGRATION_CHAT_CALL_MISSED", [
368 '#NAME#' => $otherUser->getFullName(false)
369 ]);
370 $mute = false;
371 $skipCounterInc = false;
372 }
373 }
374
375 $componentParams['MESSAGE_TEXT'] = $message;
376 $this->sendMessage($message, $mute, $skipCounterInc, $componentParams);
377 }
378 }
379
380 public function onCallCreate(): bool
381 {
382 $this->sendMessagesCallStart();
383
384 return true;
385 }
386
387 public function sendMessagesCallStart(): void
388 {
389 $message = Loc::getMessage("IM_CALL_INTEGRATION_CHAT_CALL_STARTED_V2", [
390 "#ID#" => $this->call->getId()
391 ]);
393 'MESSAGE_TYPE' => 'START',
394 'CALL_ID' => $this->call->getId(),
395 'MESSAGE_TEXT' => $message,
396 ];
397
398 $this->sendMessage($message, self::MUTE_MESSAGE, true, $componentParams);
399 }
400
401 public function sendMessageDeferred($message, $muted = false, $skipCounterInc = false, $componentParams = [])
402 {
403 Application::getInstance()->addBackgroundJob([$this, 'sendMessage'], [$message, $muted, $skipCounterInc, $componentParams]);
404 }
405
406 public function isBroadcast()
407 {
408 return
409 $this->chatFields['entity_type'] === \Bitrix\Im\Alias::ENTITY_TYPE_VIDEOCONF
410 && $this->chatFields['entity_data_1'] === 'BROADCAST';
411 }
412
413 public function sendMessage($message, $muted = false, $skipCounterInc = false, $componentParams = [])
414 {
415 $initiator = $this->getCall()->getInitiatorId();
416 if (isset($componentParams['INITIATOR_ID']))
417 {
418 $initiator = $componentParams['INITIATOR_ID'];
419 }
420
421 $chatId = $this->call->getChatId();
422 if (!empty($this->call->getParentId()))
423 {
424 //todo: Remove it
426 }
427
428 \CIMMessenger::add([
429 'WAIT_FULL_EXECUTION' => 'N',
430 'TO_CHAT_ID' => $chatId,
431 'MESSAGE_TYPE' => $this->isPrivateChat() ? IM_MESSAGE_PRIVATE : IM_MESSAGE_CHAT,
432 'FROM_USER_ID' => $initiator,
433 'MESSAGE' => $message,
434 'PUSH' => 'N',
435 'SKIP_COUNTER_INCREMENTS' => $skipCounterInc ? 'Y' : 'N',
436 'PARAMS' => [
437 'NOTIFY' => $muted ? 'N': 'Y',
438 'COMPONENT_ID' => 'CallMessage',
439 'COMPONENT_PARAMS' => $componentParams,
440 ]
441 ]);
442 }
443
444 public function toArray($initiatorId = 0)
445 {
446 if($initiatorId == 0)
447 {
448 $initiatorId = $this->initiatorId;
449 }
450
451 return [
452 'type' => $this->getEntityType(),
453 'id' => (string)$this->getEntityId($initiatorId), //todo: Cast to string for compatibility with immobile. Remove it in a while
454 'chatId' => $this->chatId,
455 'name' => $this->getName($initiatorId),
456 'avatar' => $this->getAvatar($initiatorId),
457 'avatarColor' => $this->getAvatarColor($initiatorId),
458 'userCounter' => count($this->chatUsers),
459 'advanced' => [
460 'chatType' => $this->chatFields['type'],
461 'entityType' => $this->chatFields['entity_type'],
462 'entityId' => $this->chatFields['entity_id'],
463 'entityData1' => $this->chatFields['entity_data_1'],
464 'entityData2' => $this->chatFields['entity_data_2'],
465 'entityData3' => $this->chatFields['entity_data_3']
466 ]
467 ];
468 }
469
470 public function canExtendChat(): bool
471 {
472 if (!$this->chatFields)
473 {
474 return false;
475 }
476 if ($this->chatFields['message_type'] === IM_MESSAGE_PRIVATE)
477 {
478 return true;
479 }
480 $entityType = $this->chatFields['entity_type'];
481 $options = \CIMChat::GetChatOptions();
482 return (bool)($options[$entityType]['EXTEND'] ?? true);
483 }
484
485 public function getCallDuration(): string
486 {
487 $interval = $this->call->getStartDate()->getDiff($this->call->getEndDate());
488
489 [$hours, $minutes, $seconds] = explode(' ', $interval->format('%H %I %S'));
490 $result = [];
491
492 if ((int)$hours > 0)
493 {
494 $result[] = Loc::getMessage("IM_CALL_INTEGRATION_CHAT_CALL_DURATION_HOURS", [
495 "#HOURS#" => (int)$hours
496 ]);
497 }
498
499 if ((int)$minutes > 0)
500 {
501 $result[] = Loc::getMessage("IM_CALL_INTEGRATION_CHAT_CALL_DURATION_MINUTES", [
502 "#MINUTES#" => (int)$minutes
503 ]);
504 }
505
506 if ((int)$seconds > 0 && !((int)$hours > 0))
507 {
508 $result[] = Loc::getMessage("IM_CALL_INTEGRATION_CHAT_CALL_DURATION_SECONDS", [
509 "#SECONDS#" => (int)$seconds
510 ]);
511 }
512
513 return implode(" ", $result);
514 }
515
516 private function getChatFields(\Bitrix\Im\V2\Chat $chat): array
517 {
518 return $chat->toPullFormat();
519 }
520}
if(!is_object($USER)||! $USER->IsAuthorized()) $userId
Определения check_mail.php:18
const ENTITY_TYPE_VIDEOCONF
Определения alias.php:14
const AUTH_TYPE
Определения auth.php:13
const STATE_FINISHED
Определения call.php:29
const STATE_INVITING
Определения call.php:27
const STATE_NEW
Определения call.php:26
const STATE_BUSY
Определения calluser.php:16
const STATE_DECLINED
Определения calluser.php:15
const STATE_CALLING
Определения calluser.php:14
const STATE_UNAVAILABLE
Определения calluser.php:12
toArray($initiatorId=0)
Определения chat.php:444
getAvatarColor($currentUserId)
Определения chat.php:234
isPrivateChat()
Определения chat.php:253
getManagerIds()
Определения chat.php:180
canStartCall(int $userId)
Определения chat.php:128
canExtendChat()
Определения chat.php:470
onUserAdd($userId)
Определения chat.php:258
__construct(Call $call, $entityId)
Определения chat.php:25
sendMessagesCallStart()
Определения chat.php:387
getCallDuration()
Определения chat.php:485
getName($currentUserId)
Определения chat.php:196
onStateChange($state, $prevState)
Определения chat.php:315
checkAccess(int $userId)
Определения chat.php:111
getEntityId($currentUserId=0)
Определения chat.php:80
const MUTE_MESSAGE
Определения chat.php:23
onExistingUsersInvite($userIds)
Определения chat.php:297
getEntityType()
Определения chat.php:75
sendMessage($message, $muted=false, $skipCounterInc=false, $componentParams=[])
Определения chat.php:413
getAvatar($currentUserId)
Определения chat.php:215
sendMessageDeferred($message, $muted=false, $skipCounterInc=false, $componentParams=[])
Определения chat.php:401
static isChatId($id)
Определения common.php:58
static getChatId($dialogId, $userId=null)
Определения dialog.php:93
static hasAccess($dialogId, $userId=null)
Определения dialog.php:184
static getInstance($userId=null)
Определения user.php:45
static getInstance()
Определения application.php:98
static getInstance()
Определения servicelocator.php:33
static isModuleInstalled($moduleName)
Определения modulemanager.php:125
static IsFriends($firstUserID, $secondUserID)
Определения user_relations.php:355
const PRIVACY_RESULT_CONTACT
Определения im_settings.php:29
static GetPrivacy($type, $userId=false)
Определения im_settings.php:519
const PRIVACY_CALL
Определения im_settings.php:25
$options
Определения commerceml2.php:49
$hours
Определения cron_html_pages.php:15
</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
$componentParams
Определения group_wiki_index.php:20
const IM_MESSAGE_CHAT
Определения include.php:23
const IM_MESSAGE_PRIVATE
Определения include.php:22
Определения auth.php:9
Определения ActionUuid.php:3
$entityId
Определения payment.php:4
$message
Определения payment.php:8
if( $daysToExpire >=0 &&$daysToExpire< 60 elseif)( $daysToExpire< 0)
Определения prolog_main_admin.php:393
</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