Bitrix-D7 23.9
 
Загрузка...
Поиск...
Не найдено
NotifyChat.php
1<?php
2
3namespace Bitrix\Im\V2\Chat;
4
22
23class NotifyChat extends Chat
24{
25 protected function getDefaultType(): string
26 {
27 return self::IM_TYPE_SYSTEM;
28 }
29
30 protected function checkAccessWithoutCaching(int $userId): bool
31 {
32 return false;
33 }
34
39 public function allowMention(): bool
40 {
41 return false;
42 }
43
44
45 public function getStartId(?int $userId = null): int
46 {
47 return 0;
48 }
49
50 protected function prepareParams(array $params = []): Result
51 {
52 $result = new Result();
53
54 if (!isset($params['AUTHOR_ID']))
55 {
56 if (!isset($params['TO_USER_ID']))
57 {
58 return $result->addError(new ChatError(ChatError::WRONG_RECIPIENT));
59 }
60
61 $params['AUTHOR_ID'] = $params['TO_USER_ID'];
62 }
63
64 $result->setResult($params);
65
66 return $result;
67 }
68
69 public static function getByUser(?int $userId = null): ?NotifyChat
70 {
71 return ChatFactory::getInstance()->getNotifyFeed($userId);
72 }
73
85 public static function find(array $params = [], ?Context $context = null): Result
86 {
87 $result = new Result;
88
89 if (empty($params['TO_USER_ID']))
90 {
91 $context = $context ?? Locator::getContext();
92 $params['TO_USER_ID'] = $context->getUserId();
93 }
94
95 $params['TO_USER_ID'] = (int)$params['TO_USER_ID'];
96 if ($params['TO_USER_ID'] <= 0)
97 {
98 return $result->addError(new ChatError(ChatError::WRONG_RECIPIENT));
99 }
100
101 $blockedExternalAuthId = \Bitrix\Im\Model\UserTable::filterExternalUserTypes(['replica']);
102 $res = \Bitrix\Im\Model\UserTable::getById($params['TO_USER_ID']);
103 if (
104 !($userData = $res->fetch())
105 || $userData['ACTIVE'] == 'N'
106 || in_array($userData['EXTERNAL_AUTH_ID'], $blockedExternalAuthId, true)
107 )
108 {
109 return $result->addError(new ChatError(ChatError::WRONG_RECIPIENT));
110 }
111
112 $connection = \Bitrix\Main\Application::getConnection();
113
114 $res = $connection->query("
115 SELECT *
116 FROM b_im_chat
117 WHERE AUTHOR_ID = " . $params['TO_USER_ID'] . " AND TYPE = '" . self::IM_TYPE_SYSTEM . "'
118 ORDER BY ID ASC
119 ");
120 if ($row = $res->fetch())
121 {
122 $result->setResult([
123 'ID' => (int)$row['ID'],
124 'TYPE' => $row['TYPE'],
125 'ENTITY_TYPE' => $row['ENTITY_TYPE'],
126 'ENTITY_ID' => $row['ENTITY_ID'],
127 ]);
128 }
129
130 return $result;
131 }
132
133 public function add(array $params, ?Context $context = null): Result
134 {
135 $result = new Result;
136
137 $paramsResult = $this->prepareParams($params);
138 if ($paramsResult->isSuccess())
139 {
140 $params = $paramsResult->getResult();
141 }
142 else
143 {
144 return $result->addErrors($paramsResult->getErrors());
145 }
146
147 $blockedExternalAuthId = \Bitrix\Im\Model\UserTable::filterExternalUserTypes(['replica']);
148 $res = \Bitrix\Im\Model\UserTable::getById($params['AUTHOR_ID']);
149 if (
150 !($userData = $res->fetch())
151 || $userData['ACTIVE'] == 'N'
152 || in_array($userData['EXTERNAL_AUTH_ID'], $blockedExternalAuthId, true)
153 )
154 {
155 return $result->addError(new ChatError(ChatError::WRONG_RECIPIENT));
156 }
157
158 $chat = new static($params);
159 $chat->save();
160
161 if ($chat->getChatId() <= 0)
162 {
163 return $result->addError(new ChatError(ChatError::CREATION_ERROR));
164 }
165
166 \Bitrix\Im\Model\RelationTable::add([
167 'CHAT_ID' => $chat->getChatId(),
168 'MESSAGE_TYPE' => \IM_MESSAGE_SYSTEM,
169 'USER_ID' => $params['AUTHOR_ID'],
170 ]);
171
172 return $result->setResult([
173 'CHAT_ID' => $chat->getChatId(),
174 'CHAT' => $chat,
175 ]);
176 }
177
185 public function sendMessage($message, $sendingConfig = null): Result
186 {
187 $result = new Result;
188
189 if (!$this->getChatId())
190 {
191 return $result->addError(new ChatError(ChatError::WRONG_TARGET_CHAT));
192 }
193
194 if (is_string($message))
195 {
196 $message = (new Message)->setMessage($message);
197 }
198 elseif (!$message instanceof Message)
199 {
200 $message = new Message($message);
201 }
202 $message
203 ->setRegistry($this->messageRegistry)
204 ->setContext($this->context)
205 ->setChatId($this->getChatId())
206 ;
207
208 if (!$message->getNotifyModule())
209 {
210 $message->setNotifyModule('im');
211 }
212 if (!$message->getNotifyEvent())
213 {
214 $message->setNotifyEvent(Notify::EVENT_DEFAULT);
215 }
216 if (!$message->getNotifyType())
217 {
218 if ($message->getAuthorId())
219 {
220 $message->setNotifyType(\IM_NOTIFY_FROM);
221 }
222 else
223 {
224 $message->setNotifyType(\IM_NOTIFY_SYSTEM);
225 }
226 }
227 if ($message->allowNotifyAnswer())
228 {
229 $message->getParams()->get(Params::CAN_ANSWER)->setValue(true);
230 }
231
232 // config for sending process
233 if ($sendingConfig instanceof SendingConfig)
234 {
235 $sendingServiceConfig = $sendingConfig;
236 }
237 else
238 {
239 $sendingServiceConfig = new SendingConfig();
240 if (is_array($sendingConfig))
241 {
242 $sendingServiceConfig->fill($sendingConfig);
243 }
244 }
245 // sending process
246 $sendService = new SendingService($sendingServiceConfig);
247 $sendService->setContext($this->context);
248
249
250 // fire event `im:OnBeforeMessageNotifyAdd` before message send
251 $eventResult = $sendService->fireEventBeforeNotifySend($this, $message);
252 if (!$eventResult->isSuccess())
253 {
254 // cancel sending by event
255 return $result->addErrors($eventResult->getErrors());
256 }
257
258 $checkResult = $this->validateMessage($message, $sendingServiceConfig);
259 if (!$checkResult->isSuccess())
260 {
261 return $result->addErrors($checkResult->getErrors());
262 }
263
264 $skipAdd = false;
265 $skipFlash = false;
266 if ($message->getNotifyType() != \IM_NOTIFY_CONFIRM)
267 {
268 $skipAdd = !\CIMSettings::GetNotifyAccess($this->getAuthorId(), $message->getNotifyModule(), $message->getNotifyEvent(), \CIMSettings::CLIENT_SITE);
269 $skipFlash = $skipAdd;
270 }
271 if (!$skipAdd && $message->isNotifyFlash() === true)
272 {
273 $skipAdd = true;
274 }
275 if ($skipAdd)
276 {
277 $message
278 ->markNotifyRead(true)
279 ->markNotifyFlash(true)
280 ;
281 }
282
283 // fill message param USERS with authorIds and drop other notify by tag
284 $this->dropOtherUserNotificationByTag($message);
285
286 if ($message->getNotifyType() == \IM_NOTIFY_CONFIRM)
287 {
288 $this->prepareConfirm($message);
289 $this->dropAllConfirmByTag($message);
290 }
291
292 $counter = 0;
293 if ($skipAdd)
294 {
295 $message->setMessageId(time());
296 }
297 else
298 {
299 // Save + Save Params
300 $saveResult = $message->save();
301 if (!$saveResult->isSuccess())
302 {
303 return $result->addErrors($saveResult->getErrors());
304 }
305
306 $messageCount = MessageTable::getCount(['=CHAT_ID' => $this->getChatId()]);
307
308 $this
309 ->setMessageCount($messageCount)
310 ->setLastMessageId($message->getMessageId())
311 ->save()
312 ;
313
314 // Unread
315 $readService = new ReadService($this->getAuthorId());
316 $readService->markNotificationUnread($message, $this->getRelations());
317
318 $counter = $readService->getCounterService()->getByChat($this->getChatId());
319 }
320
321 // fire event `im:OnAfterNotifyAdd`
322 $sendService->fireEventAfterNotifySend($this, $message);
323
324 // send Push
325 if ($sendingServiceConfig->sendPush())
326 {
327 $pushService = new PushService($sendingServiceConfig);
328 $pushService->sendPushNotification($this, $message, $counter, !$skipFlash);
329 }
330
331 // search
332 if (!$skipAdd)
333 {
334 $message->updateSearchIndex();
335 }
336
337 $result->setResult(['messageId' => $message->getMessageId()]);
338
339 return $result;
340 }
341
347 public function validateMessage(Message $message, SendingConfig $sendingServiceConfig): Result
348 {
349 $result = new Result;
350
351 if (!$this->getAuthorId())
352 {
353 return $result->addError(new ChatError(ChatError::WRONG_RECIPIENT));
354 }
355
356 $blockedExternalAuthId = UserTable::filterExternalUserTypes(['replica']);
357 $recipient = User::getInstance($this->getAuthorId());
358 if (
359 !$recipient->isActive()
360 || in_array($recipient->getExternalAuthId(), $blockedExternalAuthId, true)
361 )
362 {
363 return $result->addError(new ChatError(ChatError::WRONG_RECIPIENT));
364 }
365
366 if (
367 !$message->getMessage()
368 && !$message->getParams()->isSet(Params::ATTACH)
369 )
370 {
371 return $result->addError(new MessageError(MessageError::EMPTY_MESSAGE));
372 }
373
374 if (
375 !$message->getNotifyType()
376 || !in_array($message->getNotifyType(), [\IM_NOTIFY_CONFIRM, \IM_NOTIFY_SYSTEM, \IM_NOTIFY_FROM], true)
377 )
378 {
379 $result->addError(new MessageError(MessageError::NOTIFY_TYPE));
380 }
381 if (!$message->getNotifyModule())
382 {
383 $result->addError(new MessageError(MessageError::NOTIFY_MODULE));
384 }
385 if (!$message->getNotifyEvent())
386 {
387 $result->addError(new MessageError(MessageError::NOTIFY_EVENT));
388 }
389 if(
390 $message->getNotifyType() === \IM_NOTIFY_CONFIRM
391 && !$message->getNotifyButtons()
392 )
393 {
394 $result->addError(new MessageError(MessageError::NOTIFY_BUTTONS));
395 }
396 if(
397 $message->getNotifyType() === \IM_NOTIFY_FROM
398 && !$message->getAuthorId()
399 )
400 {
401 $result->addError(new MessageError(MessageError::WRONG_SENDER));
402 }
403
404 return $result;
405 }
406
407 public function dropAll(): void
408 {
409 $chatId = $this->getChatId();
410
411 if ($chatId === null || $chatId === 0)
412 {
413 return;
414 }
415
416 Message\MessageService::deleteByChatId($chatId, $this->getContext()->getUserId());
417 $this->setMessageCount(0)->save();
418
419 $this->sendPushDropAll();
420 }
421
429 protected function dropOtherUserNotificationByTag(Message $message): void
430 {
431 if (
432 $this->getChatId()
433 && $message->getAuthorId()
434 && $message->getNotifyTag()
435 )
436 {
437 $lastMessages = MessageTable::getList([
438 'select' => ['ID', 'AUTHOR_ID'],
439 'filter' => [
440 '=NOTIFY_TAG' => $message->getNotifyTag(),
441 '=CHAT_ID' => $this->getChatId(),
442 ]
443 ]);
444 $users = [];
445 while ($lastMessage = $lastMessages->fetch())
446 {
447 $lastMessageParams = new Params();
448 $lastMessageParams->loadByMessageId($lastMessage['ID']);
449
450 if ($lastMessageParams->isSet(Params::USERS))
451 {
452 $users = array_merge($users, $lastMessageParams->get(Params::USERS)->getValue());
453 }
454 $users[] = (int)$lastMessage['AUTHOR_ID'];
455
456 \CIMNotify::Delete($lastMessage['ID']);
457 }
458 $message->getParams()
459 ->get(Params::USERS)
460 ->setValue(array_unique($users))
461 ->unsetValue($message->getAuthorId())
462 ;
463 }
464 }
465
466 protected function prepareConfirm(Message $message): void
467 {
468 if ($message->getNotifyType() == \IM_NOTIFY_CONFIRM)
469 {
470 if (!empty($message->getNotifyButtons()))
471 {
472 $buttons = $message->getNotifyButtons();
473 foreach ($buttons as $index => $button)
474 {
475 if (
476 is_array($button)
477 && !empty($button['TITLE'])
478 && !empty($button['VALUE'])
479 && !empty($button['TYPE'])
480 )
481 {
482 $button['TITLE'] = htmlspecialcharsbx($button['TITLE']);
483 $button['VALUE'] = htmlspecialcharsbx($button['VALUE']);
484 $button['TYPE'] = htmlspecialcharsbx($button['TYPE']);
485 $buttons[$index] = $button;
486 }
487 else
488 {
489 unset($buttons[$index]);
490 }
491 }
492 }
493 else
494 {
495 $buttons = [
496 [
497 'TITLE' => Loc::getMessage('IM_NOTIFY_CONFIRM_BUTTON_ACCEPT'),
498 'VALUE' => 'Y',
499 'TYPE' => 'accept'
500 ],
501 [
502 'TITLE' => Loc::getMessage('IM_NOTIFY_CONFIRM_BUTTON_CANCEL'),
503 'VALUE' => 'N',
504 'TYPE' => 'cancel'
505 ],
506 ];
507 }
508
509 $message->setNotifyButtons($buttons);
510 }
511 }
512
513 protected function dropAllConfirmByTag(Message $message): void
514 {
515 if (
516 $message->getNotifyType() == \IM_NOTIFY_CONFIRM
517 && !empty($message->getNotifyTag())
518 )
519 {
520 \CIMNotify::DeleteByTag($message->getNotifyTag());
521 }
522 }
523
524 protected function sendPushDropAll(): void
525 {
526 if (Loader::includeModule('pull'))
527 {
528 \Bitrix\Pull\Event::add(
529 $this->getContext()->getUserId(),
530 [
531 'module_id' => 'im',
532 'command' => 'notifyDeleteAll',
533 'params' => [
534 'chatId' => $this->getChatId(),
535 ],
536 'extra' => \Bitrix\Im\Common::getPullExtra()
537 ]
538 );
539 \Bitrix\Pull\MobileCounter::send($this->getContext()->getUserId());
540 }
541 }
542
543 protected function addIndex(): Chat
544 {
545 return $this;
546 }
547
548 protected function updateIndex(): Chat
549 {
550 return $this;
551 }
552}
static getPullExtra()
Definition common.php:128
const EVENT_DEFAULT
Definition notify.php:11
add(array $params, ?Context $context=null)
dropAllConfirmByTag(Message $message)
static getByUser(?int $userId=null)
sendMessage($message, $sendingConfig=null)
static find(array $params=[], ?Context $context=null)
validateMessage(Message $message, SendingConfig $sendingServiceConfig)
getStartId(?int $userId=null)
prepareParams(array $params=[])
prepareConfirm(Message $message)
checkAccessWithoutCaching(int $userId)
dropOtherUserNotificationByTag(Message $message)
getParams(bool $disallowLazyLoad=false)
Definition Message.php:313
static getMessage($code, $replace=null, $language=null)
Definition loc.php:29
addError(Error $error)
Definition result.php:50