<?PHP
class Messages {
/*
Отправка сообщения
*/
public function Send($peerid, $message) {
try {
$message = TextClear($message);
if(empty($message)) {
throw new Exception(getLang('messenger_error_valid'));
}
$ossl = new OSSL($_SERVER['SERVER_NAME'] . $peerid);
$cryptResult = $ossl->Encrypt($message);
if(strlen($cryptResult['cipherText']) > 2048) {
throw new Exception(getLang('messenger_error_lenght'));
}
$sth = pdo()->prepare('INSERT INTO `messages`(`userid`, `peerid`, `ready`, `cipher_text`, `tag`, `iv`, `date`) VALUES (:userid, :peerid, :ready, :cipher_text, :tag, :iv, :date)');
$sth->execute([
':userid' => $_SESSION['id'],
':peerid' => $peerid,
':ready' => json_encode([
$_SESSION['id']
]),
':cipher_text' => $cryptResult['cipherText'],
':tag' => $cryptResult['tag'],
':iv' => $cryptResult['iv'],
':date' => time()
]);
dialogs()->Update($peerid);
return pdo()->lastInsertId();
}
catch(Exception $e) {
throw new Exception($e->getMessage());
}
}
/*
Получения данных по Индексу
*/
public function Get($id) {
try {
$sth = pdo()->prepare('SELECT * FROM `messages` WHERE `id`=:id LIMIT 1');
$sth->execute([
':id' => $id
]);
if(!$sth->rowCount()) {
return null;
}
return $sth->fetch(PDO::FETCH_OBJ);
}
catch(Exception $e) {
return null;
}
}
/*
Получение GUI сообщения
*/
public function GetMessagesGUI($peerid) {
try {
$sth = pdo()->prepare('SELECT * FROM `messages` WHERE `peerid`=:peerid ORDER BY `id` DESC LIMIT 15');
$sth->execute([
':peerid' => $peerid
]);
if(!$sth->rowCount()) {
throw new Exception('');
}
$ossl = new OSSL($_SERVER['SERVER_NAME'] . $peerid);
while($Message = $sth->fetch(PDO::FETCH_OBJ)) {
if(!$this->isReady($Message->id, $_SESSION['id'])) {
$this->setReady($Message->id, $_SESSION['id']);
}
if($this->isHidden($Message->id, $_SESSION['id'])) {
continue;
}
$UserData = users()->Get($Message->userid);
tpl()->AddCell('Messages', tpl()->Set([
'{id}' => $Message->id,
'{peerid}' => $peerid,
'{fileid}' => isset($Message->fileid) ? $Message->fileid : 'NULL',
'{image}' => $UserData->image,
'{my}' => ($Message->userid == $_SESSION['id']) ? ' My' : '',
'{message}' => $ossl->Decrypt($Message->cipher_text, $Message->tag, $Message->iv),
'{date}' => dateRussian($Message->date)
], tpl()->Get('elements/messenger/message')));
}
return tpl()->Execute(
tpl()->GetCell('Messages')
);
}
catch(Exception $e) {
throw new Exception('');
}
}
/*
Последние сообщение
*/
public function GetLastMessage($peerid) {
try {
$sth = pdo()->prepare('SELECT * FROM `messages` WHERE `peerid`=:peerid ORDER BY `id` DESC');
$sth->execute([
':peerid' => $peerid
]);
if(!$sth->rowCount()) {
throw new Exception(getLang('messenger_error_message'));
}
$ossl = new OSSL($_SERVER['SERVER_NAME'] . $peerid);
while($Message = $sth->fetch(PDO::FETCH_OBJ)) {
$String = $ossl->Decrypt($Message->cipher_text, $Message->tag, $Message->iv);
if($this->isHidden($Message->id, $_SESSION['id'])) {
continue;
}
if($Message->userid == $_SESSION['id']) {
return getLang('messenger_you', [$String]);
}
else {
$UserData = users()->Get($Message->userid);
return $UserData->first_name . ': ' . $String;
}
}
throw new Exception(getLang('messenger_error_message'));
}
catch(Exception $e) {
return $e->getMessage();
}
}
/*
Время последнего сообщения
*/
public function GetLastDate($peerid) {
try {
$sth = pdo()->prepare('SELECT * FROM `messages` WHERE `peerid`=:peerid ORDER BY `id` DESC LIMIT 1');
$sth->execute([
':peerid' => $peerid
]);
if(!$sth->rowCount()) {
return '';
}
$Message = $sth->fetch(PDO::FETCH_OBJ);
return dateRussian($Message->date);
}
catch(Exception $e) {
return $e->getMessage();
}
}
/*
Получение сообщений по диапазону
*/
public function GetMessageRange($peerid, $start = 0) {
try {
$sth = pdo()->prepare('SELECT * FROM `messages` WHERE `peerid`=:peerid AND (`id` > :start) ORDER BY `id` DESC LIMIT 15');
$sth->execute([
':peerid' => $peerid,
':start' => empty($start) ? 0 : $start
]);
if(!$sth->rowCount()) {
throw new Exception('');
}
$ossl = new OSSL($_SERVER['SERVER_NAME'] . $peerid);
while($Message = $sth->fetch(PDO::FETCH_OBJ)) {
if(!$this->isReady($Message->id, $_SESSION['id'])) {
$this->setReady($Message->id, $_SESSION['id']);
}
if($this->isHidden($Message->id, $_SESSION['id'])) {
continue;
}
$UserData = users()->Get($Message->userid);
tpl()->AddCell('Messages', tpl()->Set([
'{id}' => $Message->id,
'{peerid}' => $peerid,
'{fileid}' => isset($Message->fileid) ? $Message->fileid : 'NULL',
'{image}' => $UserData->image,
'{my}' => ($Message->userid == $_SESSION['id']) ? ' My' : '',
'{message}' => $ossl->Decrypt($Message->cipher_text, $Message->tag, $Message->iv),
'{date}' => dateRussian($Message->date)
], tpl()->Get('elements/messenger/message')));
}
return tpl()->Execute(
tpl()->GetCell('Messages')
);
}
catch(Exception $e) {
throw new Exception('');
}
}
/*
Получение старых сообщений
*/
public function GetMessageRangeOld($peerid, $start = 0) {
try {
$sth = pdo()->prepare('SELECT * FROM `messages` WHERE `peerid`=:peerid AND (`id` < :start) ORDER BY `id` DESC LIMIT 15');
$sth->execute([
':peerid' => $peerid,
':start' => empty($start) ? 0 : $start
]);
if(!$sth->rowCount()) {
throw new Exception('');
}
$ossl = new OSSL($_SERVER['SERVER_NAME'] . $peerid);
while($Message = $sth->fetch(PDO::FETCH_OBJ)) {
if(!$this->isReady($Message->id, $_SESSION['id'])) {
$this->setReady($Message->id, $_SESSION['id']);
}
if($this->isHidden($Message->id, $_SESSION['id'])) {
continue;
}
$UserData = users()->Get($Message->userid);
tpl()->AddCell('Messages', tpl()->Set([
'{id}' => $Message->id,
'{peerid}' => $peerid,
'{fileid}' => isset($Message->fileid) ? $Message->fileid : 'NULL',
'{image}' => $UserData->image,
'{my}' => ($Message->userid == $_SESSION['id']) ? ' My' : '',
'{message}' => $ossl->Decrypt($Message->cipher_text, $Message->tag, $Message->iv),
'{date}' => dateRussian($Message->date)
], tpl()->Get('elements/messenger/message')));
}
return tpl()->Execute(
tpl()->GetCell('Messages')
);
}
catch(Exception $e) {
throw new Exception('');
}
}
/*
Получить индекс последнего сообщения
*/
public function GetLastId($peerid) {
$sth = pdo()->prepare('SELECT * FROM `messages` WHERE `peerid`=:peerid ORDER BY `id` DESC LIMIT 1');
$sth->execute([
':peerid' => $peerid
]);
if(!$sth->rowCount()) {
return null;
}
return $sth->fetch(PDO::FETCH_OBJ)->id;
}
/*
Количество непрочитанных сообщений
*/
public function rowNotReady($peerid) {
try {
$sth = pdo()->prepare('SELECT * FROM `messages` WHERE `userid`!=:userid AND `peerid`=:peerid');
$sth->execute([
':userid' => $_SESSION['id'],
':peerid' => $peerid
]);
$rowCount = 0;
if(!$sth->rowCount()) {
return $rowCount;
}
$rowCount = 0;
while($Message = $sth->fetch(PDO::FETCH_OBJ)) {
if(!$this->isReady($Message->id, $_SESSION['id'])) {
$rowCount++;
}
}
return $rowCount;
}
catch(Exception $e) {
return 0;
}
}
/*
Проверка сообщения на прочитывание
*/
public function isReady($messageid, $userid) {
try {
$dataMessage = $this->Get($messageid);
if(empty($dataMessage)) {
return false;
}
$userids = json_decode(
$dataMessage->ready,
true
);
foreach($userids as $key => $uid) {
if($uid == $userid) {
return true;
}
}
return false;
}
catch(Exception $e) {
return false;
}
}
/*
Пометка как прочитанное
*/
public function setReady($messageid, $userid) {
try {
$Message = $this->Get($messageid);
$Readys = json_decode(
$Message->ready,
true
);
$Readys[] = $userid;
$sth = pdo()->prepare('UPDATE `messages` SET `ready`=:ready WHERE `id`=:id LIMIT 1');
$sth->execute([
':ready' => json_encode($Readys),
':id' => $messageid
]);
return true;
}
catch(Exception $e) {
return false;
}
}
/*
Отправка файла
*/
public function fileSend($peerid, $fileid) {
try {
$message = '<i class="bi bi-stickies"></i> ' . getLang('messenger_error_clip');
if(empty($message)) {
throw new Exception(getLang('messenger_error_valid'));
}
$ossl = new OSSL($_SERVER['SERVER_NAME'] . $peerid);
$cryptResult = $ossl->Encrypt($message);
$sth = pdo()->prepare('INSERT INTO `messages`(`userid`, `peerid`, `fileid`, `ready`, `cipher_text`, `tag`, `iv`, `date`) VALUES (:userid, :peerid, :fileid, :ready, :cipher_text, :tag, :iv, :date)');
$sth->execute([
':userid' => $_SESSION['id'],
':peerid' => $peerid,
':fileid' => $fileid,
':ready' => json_encode([$_SESSION['id']]),
':cipher_text' => $cryptResult['cipherText'],
':tag' => $cryptResult['tag'],
':iv' => $cryptResult['iv'],
':date' => time()
]);
return pdo()->lastInsertId();
}
catch(Exception $e) {
throw new Exception($e->getMessage());
}
}
/*
Проверка на скрытость
*/
public function isHidden($msgid, $userid) {
try {
$dataMessage = $this->Get($msgid);
if(empty($dataMessage->hidden)) {
return false;
}
$hideList = json_decode($dataMessage->hidden, true);
foreach($hideList as $key => $uid) {
if($uid == $userid) {
return true;
}
}
return false;
}
catch(Exception $e) {
return true;
}
}
/*
Добавление чтения
*/
public function addHidden($msgid, $userid) {
try {
$dataMessage = $this->Get($msgid);
if(isset($dataMessage->hidden)) {
$hideList = json_decode($dataMessage->hidden, true);
foreach($hideList as $key => $uid) {
if($uid == $userid) {
return true;
}
}
}
$hideList[] = $userid;
$sth = pdo()->prepare('UPDATE `messages` SET `hidden`=:hidden WHERE `id`=:msgid LIMIT 1');
$sth->execute([
':hidden' => json_encode($hideList),
':msgid' => $msgid
]);
return true;
}
catch(Exception $e) {
throw new Exception($e->getMessage());
}
}
}