portal.mkgtu.ru/common/modules/abiturient/models/chat/ChatHistoryBase.php

387 lines
9.5 KiB
PHP
Executable File
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
namespace common\modules\abiturient\models\chat;
use common\components\behaviors\timestampBehavior\TimestampBehaviorMilliseconds;
use common\components\DateTimeHelper;
use common\components\notification\factories\NotifierFactory;
use common\models\errors\RecordNotValid;
use common\models\traits\HtmlPropsEncoder;
use common\models\User;
use Throwable;
use Yii;
use yii\db\ActiveQuery;
use yii\db\ActiveRecord;
use yii\helpers\ArrayHelper;
use yii\web\Controller;
class ChatHistoryBase extends ActiveRecord
{
use HtmlPropsEncoder;
public const EVENT_SEND_MESSAGE = 1;
public const EVENT_ENDING_CHAT = 2;
public const EVENT_STARTING_CHAT = 3;
public const EVENT_STARTING_CHAT_AGAIN = 4;
public const EVENT_MANAGER_CHANGE_CHAT = 5;
public const EVENT_SEND_FILE = 6;
public static function tableName()
{
return '{{%chat_history}}';
}
public function behaviors()
{
return [TimestampBehaviorMilliseconds::class];
}
public function rules()
{
return [
[
['chat_id'],
'required'
],
[
[
'event',
'chat_id',
'file_id',
'created_at',
'message_id',
'updated_at',
],
'integer'
],
[
['chat_id'],
'exist',
'skipOnError' => true,
'targetClass' => ChatBase::class,
'targetAttribute' => ['chat_id' => 'id']
],
[
['message_id'],
'exist',
'skipOnError' => true,
'targetClass' => ChatMessageBase::class,
'targetAttribute' => ['message_id' => 'id']
],
[
['file_id'],
'exist',
'skipOnError' => true,
'targetClass' => ChatFileBase::class,
'targetAttribute' => ['file_id' => 'id']
],
];
}
public function attributeLabels()
{
return [];
}
public function getChat(): ActiveQuery
{
return $this->hasOne(ChatBase::class, ['id' => 'chat_id']);
}
public function getMessage(): ActiveQuery
{
return $this->hasOne(ChatMessageBase::class, ['id' => 'message_id']);
}
public function getFile(): ActiveQuery
{
$user = Yii::$app->user->identity;
$chatFilesClass = ChatFileBase::class;
if ($user->isInRole(User::ROLE_MANAGER)) {
$chatFilesClass = ManagerChatFile::class;
} elseif ($user->isInRole(User::ROLE_ABITURIENT)) {
$chatFilesClass = AbiturientChatFile::class;
}
return $this->hasOne($chatFilesClass, ['id' => 'file_id']);
}
public static function addedNewMessage(ChatMessageBase $message): bool
{
$chatHistory = new static();
$chatHistory->event = static::EVENT_SEND_MESSAGE;
$chatHistory->message_id = $message->id;
$chatHistory->chat_id = $message->chat_id;
if (!$chatHistory->save()) {
throw new RecordNotValid($chatHistory);
}
return static::sendNotification($message);
}
public static function addedNewFile(ChatFileBase $file): bool
{
$chatHistory = new static();
$chatHistory->event = static::EVENT_SEND_FILE;
$chatHistory->file_id = $file->id;
$chatHistory->chat_id = $file->chat_id;
if (!$chatHistory->save()) {
throw new RecordNotValid($chatHistory);
}
return static::sendNotification($file);
}
public function renderEvent(Controller $controller, User $user): string
{
switch ($this->event) {
case ChatHistoryBase::EVENT_SEND_MESSAGE:
return $this->message->render($controller, $user);
case ChatHistoryBase::EVENT_SEND_FILE:
return $this->file->render($controller, $user);
case ChatHistoryBase::EVENT_ENDING_CHAT:
case ChatHistoryBase::EVENT_STARTING_CHAT:
$message = '';
if ($this->event === ChatHistoryBase::EVENT_ENDING_CHAT) {
$message = Yii::t('abiturient/chat-history-base/all', 'Сообщение о том что модератор завершил чат; в окне истории чата: `Модератор завершил заявку`');
} elseif ($this->event === ChatHistoryBase::EVENT_STARTING_CHAT) {
$message = Yii::t('abiturient/chat-history-base/all', 'Сообщение о том что модератор начал чат; в окне истории чата: `Модератор принял заявку в обработку`');
}
$data = [
'time' => DateTimeHelper::dateFromMstime('d.m.Y H:i', $this->created_at),
'message' => $message
];
$path = '@chatPartialView/history-separator';
return $controller->renderPartial($path, $data);
case ChatHistoryBase::EVENT_STARTING_CHAT_AGAIN:
$data = [
'time' => DateTimeHelper::dateFromMstime('d.m.Y H:i', $this->created_at),
'message' => Yii::t(
'abiturient/chat-history-base/all',
'Сообщение о том что поступающий заново открыл чат; в окне истории чата: `Поступающий повторно открыл заявку`'
),
];
case ChatHistoryBase::EVENT_MANAGER_CHANGE_CHAT:
$data = [
'time' => DateTimeHelper::dateFromMstime('d.m.Y H:i', $this->created_at),
'message' => Yii::t(
'abiturient/chat-history-base/all',
'Сообщение о том что модератор переадресовал чат; в окне истории чата: `Заявка была переадресована`'
),
];
$path = '@chatPartialView/history-separator';
return $controller->renderPartial($path, $data);
}
return '';
}
public static function sendNotification($chatBlob): bool
{
$title = Yii::t(
'abiturient/chat-history-base/all',
'Текст уведомления о новом сообщении в чате: `Пользователь {user} отправил вам сообщение.`',
['user' => ArrayHelper::getValue($chatBlob, 'author.nickname')]
);
$body = $chatBlob->renderForNotification();
$otherUsersIds = ChatUserBase::getOtherUsersIds($chatBlob->chat_id, $chatBlob->author_id);
$sendMessagesId = [];
$sendId = ArrayHelper::getValue($chatBlob, 'author.user_id');
try {
$sendMessagesId = NotifierFactory::getChatNotifier($sendId)->send(
$title,
$body,
$otherUsersIds,
);
} catch (Throwable $th) {
Yii::error(
"Отправки уведомлений: {$th->getMessage()}",
'ChatHistoryBase.sendNotification'
);
return false;
}
if (count($sendMessagesId) != count($otherUsersIds)) {
$sendMessagesCount = count($sendMessagesId);
$otherUsersMessagesCount = count($otherUsersIds);
Yii::error(
"Не соответствует кол-во отправленных уведомлений ({$sendMessagesCount}) с кол-вом уведомлений на отправку ({$otherUsersMessagesCount})",
'ChatHistoryBase.sendNotification'
);
return false;
}
return true;
}
public static function managerEndingChat(ChatBase $chat): void
{
static::createEventOnStatusChange($chat, static::EVENT_ENDING_CHAT);
}
public static function managerRedirectChat(ChatBase $chat): void
{
static::createEventOnStatusChange($chat, static::EVENT_MANAGER_CHANGE_CHAT);
}
public static function abitOpenAgainChat(ChatBase $chat): void
{
$oldStatus = $chat->getOldAttribute('status');
if (
$oldStatus != $chat->status &&
$chat->status == ChatBase::STATUS_OPEN_AGAIN
) {
static::createEventOnStatusChange($chat, static::EVENT_STARTING_CHAT_AGAIN);
}
}
public static function managerStartingChat(ChatBase $chat): void
{
$oldStatus = $chat->getOldAttribute('status');
if (
$oldStatus != $chat->status &&
$chat->status == ChatBase::STATUS_ACTIVE
) {
static::createEventOnStatusChange($chat, static::EVENT_STARTING_CHAT);
}
}
public static function createEventOnStatusChange(ChatBase $chat, int $event): void
{
$chatHistory = new static();
$chatHistory->event = $event;
$chatHistory->chat_id = $chat->id;
if (!$chatHistory->save()) {
throw new RecordNotValid($chatHistory);
}
}
}