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); } } }