1C-Bitrix 25.700.0
Загрузка...
Поиск...
Не найдено
ImportService.php
См. документацию.
1<?php
2
3namespace Bitrix\Im\V2\Import;
4
5use Bitrix\Im\Chat;
6use Bitrix\Im\Model\ChatTable;
7use Bitrix\Im\Model\EO_Relation;
8use Bitrix\Im\Model\EO_Relation_Collection;
9use Bitrix\Im\Model\MessageTable;
10use Bitrix\Im\Model\RelationTable;
11use Bitrix\Im\Model\UserTable;
12use Bitrix\Im\Recent;
13use Bitrix\Im\User;
14use Bitrix\Im\V2\Chat\ChatError;
15use Bitrix\Im\V2\Result;
16use Bitrix\Main\Application;
17use Bitrix\Main\Loader;
18use Bitrix\Main\Localization\Loc;
19use Bitrix\Main\ORM\Query\Query;
20use Bitrix\Main\Type\DateTime;
21use Bitrix\Rest\AppTable;
22
24{
25 public const IMPORT_GROUP_CHAT_ENTITY_TYPE = 'IMPORT_GROUP';
26 public const IMPORT_PRIVATE_CHAT_ENTITY_TYPE = 'IMPORT_PRIVATE';
27 public const IMPORT_GROUP_FINISH_ENTITY_TYPE = 'IMPORT_GROUP_FINISH';
28 public const IMPORT_PRIVATE_FINISH_ENTITY_TYPE = 'IMPORT_PRIVATE_FINISH';
29 public const IMPORT_ARCHIVE_ENTITY_TYPE = 'IMPORT_ARCHIVE';
30
31 private int $userId;
32 private array $chat;
33 private ImportSendingService $sendingService;
34
35 public function __construct(array $chat, ?int $userId = null, ?ImportSendingService $sendingService = null)
36 {
37 $this->chat = $chat;
38 if (isset($userId))
39 {
40 $this->userId = $userId;
41 }
42 if (isset($sendingService))
43 {
44 $this->sendingService = $sendingService;
45 }
46 else
47 {
48 $this->sendingService = new ImportSendingService($chat);
49 }
50 }
51
52 public static function create(array $chatData): Result
53 {
54 $result = new Result();
55
56 $chatData['ENTITY_TYPE'] =
57 $chatData['TYPE'] === \IM_MESSAGE_PRIVATE
58 ? self::IMPORT_PRIVATE_CHAT_ENTITY_TYPE
59 : self::IMPORT_GROUP_CHAT_ENTITY_TYPE
60 ;
61 $chatData['SKIP_ADD_MESSAGE'] = 'Y';
62
63 $chatService = new \CIMChat(0);
64 $chatId = $chatService->Add($chatData);
65
66 if ($chatId === 0)
67 {
68 return $result->addError(new ChatError(ChatError::CREATION_ERROR));
69 }
70
71 return $result->setResult([
72 'CHAT_ID' => $chatId,
73 'TYPE' => $chatData['TYPE']
74 ]);
75 }
76
78 {
79 return $this->sendingService->addMessages($messages);
80 }
81
83 {
84 return $this->sendingService->updateMessages($messages);
85 }
86
87 public function abort(): Result
88 {
89 $result = new Result();
90 \CIMChat::deleteChat($this->chat);
91
92 return $result;
93 }
94
95 public function commitGroup(array $users, string $clientId): Result
96 {
97 return $this->commitCommon(
98 $users,
100 [
101 'ENTITY_TYPE' => self::IMPORT_GROUP_FINISH_ENTITY_TYPE,
102 'ENTITY_ID' => null,
103 'ENTITY_DATA_1' => $clientId
104 ]
105 );
106 }
107
108 public function commitPrivate(bool $newIsMain, bool $hideOriginal, string $clientId): Result
109 {
110 $result = new Result();
111
112 $initUsers = $this->getInitUsers();
113 $originalChat = $this->getOriginalChat($initUsers);
114 $originalChatId = null;
115 if ($originalChat !== null)
116 {
117 $originalChatId = (int)$originalChat['ID'];
118 if ($this->hasRealMessages($originalChat))
119 {
120 if ($newIsMain)
121 {
122 if ($hideOriginal)
123 {
124 $this->hideChat($originalChat, $initUsers);
125 }
126 else
127 {
128 $this->convertOriginalToGroup($originalChat, $initUsers);
129 }
130 }
131 else
132 {
133 $this->convertToGroup($initUsers);
134 $this->chat['MESSAGE_TYPE'] = \IM_MESSAGE_CHAT;
135 }
136 }
137 else
138 {
139 $this->hideChat($originalChat, $initUsers);
140 }
141 }
142
143 $this->commitCommon(
144 $initUsers,
145 $clientId,
146 [
147 'ENTITY_TYPE' => self::IMPORT_PRIVATE_FINISH_ENTITY_TYPE,
148 'ENTITY_ID' => $originalChatId,
149 'ENTITY_DATA_1' => $clientId
150 ]
151 );
152
153 if ($this->chat['MESSAGE_TYPE'] === \IM_MESSAGE_CHAT)
154 {
155 $chatService = new \CIMChat(0);
156 $managers = [];
157 foreach ($initUsers as $user)
158 {
159 $managers[$user] = true;
160 }
161 $chatService->SetManagers((int)$this->chat['ID'], $managers, false);
162 }
163
164 return $result;
165 }
166
167 private function hideChat(array $chat, array $users): void
168 {
169 $id = (int)$chat['ID'];
170
171 RelationTable::deleteByFilter(['=CHAT_ID' => $id]);
172 Recent::hide($users[0], $users[1]);
173 Recent::hide($users[1], $users[0]);
174 sort($users);
175 ChatTable::update($id, ['ENTITY_TYPE' => self::IMPORT_ARCHIVE_ENTITY_TYPE, 'ENTITY_ID' => "{$users[0]}|{$users[1]}"]);
176 }
177
178 private function getOriginalChat(array $users): ?array
179 {
180 $originalChatId = \CIMMessage::GetChatId($users[0], $users[1], false);
181 if ($originalChatId === 0)
182 {
183 return null;
184 }
185
186 return Chat::getById($originalChatId);
187 }
188
189 private function hasRealMessages(array $chat): bool
190 {
191 if ((int)$chat['MESSAGE_COUNT'] === 0)
192 {
193 return false;
194 }
195
196 if ((int)$chat['MESSAGE_COUNT'] === 1)
197 {
198 return \CIMMessageParam::Get((int)$chat['LAST_MESSAGE_ID'], 'USER_JOIN') !== null;
199 }
200
201 return true;
202 }
203
204 private function getInitUsers(): array
205 {
206 $initUsers = [];
207 [$initUsers[0], $initUsers[1]] = explode('|', $this->chat['ENTITY_DATA_1']);
208
209 return array_map('intval', $initUsers);
210 }
211
212 private function commitCommon(array $users, string $clientId, array $finishEntityData = []): Result
213 {
214 $result = new Result();
215 $chatId = (int)$this->chat['ID'];
216
217 $users = array_map('intval', $users);
218 $folderMembers = $users;
219 if (!in_array($this->userId, $users, true))
220 {
221 \CIMDisk::ChangeFolderMembers($chatId, $this->userId, false);
222 }
223 else
224 {
225 foreach ($folderMembers as $index => $folderMember)
226 {
227 if ($folderMember === $this->userId)
228 {
229 unset($folderMembers[$index]);
230 }
231 }
232 }
233
234 $this->fillChatActualData();
235 $this->addUsersInChat($this->chat, $users);
236 \CIMDisk::ChangeFolderMembers($chatId, $users);
237 ChatTable::update(
238 $chatId,
239 [
240 'ENTITY_TYPE' => $finishEntityData['ENTITY_TYPE'] ?? null,
241 'ENTITY_ID' => $finishEntityData['ENTITY_ID'] ?? null,
242 'ENTITY_DATA_1' => $finishEntityData['ENTITY_DATA_1'] ?? null,
243 'USER_COUNT' => count($users),
244 'MESSAGE_COUNT' => $this->chat['MESSAGE_COUNT'],
245 'LAST_MESSAGE_ID' => $this->chat['LAST_MESSAGE_ID'],
246 'PREV_MESSAGE_ID' => $this->chat['PREV_MESSAGE_ID'],
247 ]
248 );
249 $this->showInRecent($this->chat);
250 $this->sendFinishMessage($users, $clientId);
251
252 return $result;
253 }
254
255 private function sendFinishMessage(array $users, string $clientId): void
256 {
257 $appName = $this->getRestAppName($clientId) ?? '';
258 \CIMMessenger::Add([
259 'MESSAGE' => Loc::getMessage('IM_IMPORT_FINISH_MESSAGE', ['#APP_NAME#' => $appName]),
260 'FROM_USER_ID' => $this->chat['MESSAGE_TYPE'] === \IM_MESSAGE_PRIVATE ? $users[0] : 0,
261 'TO_CHAT_ID' => (int)$this->chat['ID'],
262 'MESSAGE_TYPE' => $this->chat['MESSAGE_TYPE'],
263 'SYSTEM' => 'Y',
264 ]);
265 }
266
267 private function fillChatActualData(): void
268 {
269 $lastMessageIds = $this->getLastMessageIds((int)$this->chat['ID']);
270 $this->chat['MESSAGE_COUNT'] = $this->getMessageCount((int)$this->chat['ID']);
271 $this->chat['LAST_MESSAGE_ID'] = $lastMessageIds[0] ?? 0;
272 $this->chat['PREV_MESSAGE_ID'] = $lastMessageIds[1] ?? 0;
273 }
274
275 private function getMessageCount(int $chatId): int
276 {
277 return MessageTable::getCount(Query::filter()->where('CHAT_ID', $chatId));
278 }
279
280 private function getLastMessageIds(int $chatId): array
281 {
282 $result = [];
283
284 $messages = MessageTable::query()
285 ->setSelect(['ID'])
286 ->where('CHAT_ID', $chatId)
287 ->setOrder(['DATE_CREATE' => 'DESC'])
288 ->setLimit(2)
289 ->fetchCollection()
290 ;
291
292 foreach ($messages as $message)
293 {
294 $result[] = $message->getId();
295 }
296
297 return $result;
298 }
299
300 private function showInRecent(array $chatData): Result
301 {
302 $relations = Chat::getRelation((int)$chatData['ID'], ['WITHOUT_COUNTERS' => 'Y']);
303
304 foreach ($relations as $userId => $relation)
305 {
306 $entityId =
307 $chatData['MESSAGE_TYPE'] === \IM_MESSAGE_PRIVATE
308 ? $this->getEntityIdForPrivateChat($relations, (int)$relation['USER_ID'])
309 : (int)$chatData['ID']
310 ;
311 \CIMContactList::SetRecent(Array(
312 'ENTITY_ID' => $entityId,
313 'MESSAGE_ID' => (int)$chatData['LAST_MESSAGE_ID'],
314 'CHAT_TYPE' => $chatData['MESSAGE_TYPE'],
315 'USER_ID' => $relation['USER_ID'],
316 'CHAT_ID' => $relation['CHAT_ID'],
317 'RELATION_ID' => $relation['ID'],
318 ));
319 }
320
321 return new Result();
322 }
323
324 private function addUsersInChat(array $chatData, array $users): void
325 {
326 $relationCollection = new EO_Relation_Collection();
327 $lastRead = new DateTime();
328
329 foreach ($users as $user)
330 {
331 $relation = new EO_Relation();
332 $relation
333 ->setChatId((int)$chatData['ID'])
334 ->setMessageType($chatData['MESSAGE_TYPE'])
335 ->setUserId($user)
336 ->setStartId(0)
337 ->setLastId((int)$chatData['LAST_MESSAGE_ID'])
338 ->setLastSendId((int)$chatData['LAST_MESSAGE_ID'])
339 ->setLastFileId(0)
340 ->setStartCounter(0)
341 ->setLastRead($lastRead)
342 ;
343 $relationCollection->add($relation);
344 }
345
346 $relationCollection->save(true);
347 }
348
349 private function getEntityIdForPrivateChat(array $relations, int $userId): int
350 {
351 foreach ($relations as $relation)
352 {
353 if ((int)$relation['USER_ID'] !== $userId)
354 {
355 return (int)$relation['USER_ID'];
356 }
357 }
358
359 return 0;
360 }
361
362 private function convertToGroup(array $users): void
363 {
364 $title = Loc::getMessage(
365 'IM_IMPORT_GROUP_FROM_PRIVATE_CHAT_TITLE',
366 [
367 '#USER_NAME_1#' => User::getInstance($users[0])->getFullName(false),
368 '#USER_NAME_2#' => User::getInstance($users[1])->getFullName(false),
369 ]
370 );
371 ChatTable::update((int)$this->chat['ID'], ['TYPE' => \IM_MESSAGE_CHAT, 'TITLE' => $title]);
372 }
373
374 private function convertOriginalToGroup(array $originalChat, array $users): void
375 {
376 $chatId = (int)$originalChat['ID'];
377 $title = Loc::getMessage(
378 'IM_IMPORT_GROUP_FROM_ORIGINAL_PRIVATE_CHAT_TITLE',
379 [
380 '#USER_NAME_1#' => User::getInstance($users[0])->getFullName(false),
381 '#USER_NAME_2#' => User::getInstance($users[1])->getFullName(false),
382 ]
383 );
384 Recent::hide($users[0], $users[1]);
385 Recent::hide($users[1], $users[0]);
386 ChatTable::update((int)$originalChat['ID'], ['TYPE' => \IM_MESSAGE_CHAT, 'TITLE' => $title]);
387 $originalChat['MESSAGE_TYPE'] = \IM_MESSAGE_CHAT;
388 $sqlUpdateRelation = "UPDATE b_im_relation SET MESSAGE_TYPE= '" . \IM_MESSAGE_CHAT . "' WHERE CHAT_ID={$chatId}";
389 Application::getConnection()->query($sqlUpdateRelation);
390 $this->showInRecent($originalChat);
391 }
392
393 private function getRestAppName(string $clientId): ?string
394 {
395 $app = AppTable::getByClientId($clientId);
396 if (!is_array($app))
397 {
398 return null;
399 }
400
401 $appNamesByPriority = [$app['MENU_NAME'], $app['MENU_NAME_DEFAULT'], $app['MENU_NAME_LICENSE'], $app['APP_NAME']];
402
403 foreach ($appNamesByPriority as $appName)
404 {
405 if ($appName !== '')
406 {
407 return $appName;
408 }
409 }
410
411 return null;
412 }
413
414 public function hasAccess(): bool
415 {
416 return $this->isImportInProgress() && self::isAdmin($this->userId);
417 }
418
419 public static function isAdmin(int $userId): bool
420 {
421 global $USER;
422 if (Loader::includeModule('bitrix24'))
423 {
424 if (
425 $USER instanceof \CUser
426 && $USER->isAuthorized()
427 && $USER->isAdmin()
428 && (int)$USER->getId() === $userId
429 )
430 {
431 return true;
432 }
433
434 return \CBitrix24::isPortalAdmin($userId);
435 }
436
437 if (
438 $USER instanceof \CUser
439 && $USER->isAuthorized()
440 && (int)$USER->getId() === $userId
441 )
442 {
443 return $USER->isAdmin();
444 }
445
446 $result = false;
447 $groups = UserTable::getUserGroupIds($userId);
448 foreach ($groups as $groupId)
449 {
450 if ((int)$groupId === 1)
451 {
452 $result = true;
453 break;
454 }
455 }
456
457 return $result;
458 }
459
460 private function isImportInProgress(): bool
461 {
462 $entityType = $this->chat['ENTITY_TYPE'] ?? '';
463
464 return (
465 $entityType === self::IMPORT_PRIVATE_CHAT_ENTITY_TYPE
466 || $entityType === self::IMPORT_GROUP_CHAT_ENTITY_TYPE
467 );
468 }
469}
static getRelation($chatId, $params=[])
Определения chat.php:93
static hide($dialogId, $userId=null)
Определения recent.php:1902
static getInstance($userId=null)
Определения user.php:45
const CREATION_ERROR
Определения ChatError.php:23
const IMPORT_PRIVATE_CHAT_ENTITY_TYPE
Определения ImportService.php:26
updateMessages(array $messages)
Определения ImportService.php:82
commitGroup(array $users, string $clientId)
Определения ImportService.php:95
static create(array $chatData)
Определения ImportService.php:52
const IMPORT_GROUP_CHAT_ENTITY_TYPE
Определения ImportService.php:25
commitPrivate(bool $newIsMain, bool $hideOriginal, string $clientId)
Определения ImportService.php:108
addMessages(array $messages)
Определения ImportService.php:77
const IMPORT_PRIVATE_FINISH_ENTITY_TYPE
Определения ImportService.php:28
const IMPORT_ARCHIVE_ENTITY_TYPE
Определения ImportService.php:29
const IMPORT_GROUP_FINISH_ENTITY_TYPE
Определения ImportService.php:27
static isAdmin(int $userId)
Определения ImportService.php:419
__construct(array $chat, ?int $userId=null, ?ImportSendingService $sendingService=null)
Определения ImportService.php:35
Определения result.php:20
static getById($id)
Определения datamanager.php:364
static GetChatId($fromUserId, $toUserId, $createIfNotExists=true)
Определения im_message.php:1459
</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_MESSAGE_CHAT
Определения include.php:23
const IM_MESSAGE_PRIVATE
Определения include.php:22
$app
Определения proxy.php:8
global $USER
Определения csv_new_run.php:40
$groups
Определения options.php:30
int $chatId
Определения Param.php:36
$user
Определения mysql_to_pgsql.php:33
$entityId
Определения payment.php:4
$message
Определения payment.php:8
</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
$messages
Определения template.php:8
$title
Определения pdf.php:123
$clientId
Определения seo_client.php:18