View file application/system/library/class.messages.php

File size: 11.67Kb
<?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());
			}
		}
	}