123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498 |
- <?php
- /* For licensing terms, see /license.txt */
- use ChamiloSession as Session;
- /**
- * Class Chat
- * @todo ChamiloSession instead of $_SESSION
- * @package chamilo.library.chat
- */
- class Chat extends Model
- {
- public $columns = array(
- 'id',
- 'from_user',
- 'to_user',
- 'message',
- 'sent',
- 'recd',
- );
- public $window_list = array();
- /**
- * The contructor sets the chat table name and the window_list attribute
- */
- public function __construct()
- {
- parent::__construct();
- $this->table = Database::get_main_table(TABLE_MAIN_CHAT);
- $this->window_list = Session::read('window_list');
- Session::write('window_list', $this->window_list);
- }
- /**
- * Get user chat status
- * @return int 0 if disconnected, 1 if connected
- */
- public function getUserStatus()
- {
- $status = UserManager::get_extra_user_data_by_field(
- api_get_user_id(),
- 'user_chat_status',
- false,
- true
- );
- return $status['user_chat_status'];
- }
- /**
- * Set user chat status
- * @param int 0 if disconnected, 1 if connected
- * @param integer $status
- *
- * @return void
- */
- public function setUserStatus($status)
- {
- UserManager::update_extra_field_value(
- api_get_user_id(),
- 'user_chat_status',
- $status
- );
- }
- public function getLatestChat($currentUserId, $userId, $latestMessages)
- {
- $items = self::getPreviousMessages(
- $currentUserId,
- $userId,
- 0,
- $latestMessages
- );
- return array_reverse($items);
- }
- /**
- * @param array $chatHistory
- * @param int $latestMessages
- * @return mixed
- */
- public function getAllLatestChats($chatHistory, $latestMessages = 5)
- {
- $currentUserId = api_get_user_id();
- $chats = [];
- if (!empty($chatHistory)) {
- foreach ($chatHistory as $chat) {
- $userId = $chat['user_info']['user_id'];
- $items = self::getLatestChat(
- $currentUserId,
- $userId,
- $latestMessages
- );
- $chats[$userId]['items'] = $items;
- }
- }
- return $chats;
- }
- /**
- * Starts a chat session and returns JSON array of status and chat history
- * @return void (prints output in JSON format)
- */
- public function startSession()
- {
- $chatList = Session::read('chatHistory');
- $chats = self::getAllLatestChats($chatList);
- $return = array(
- 'user_status' => $this->getUserStatus(),
- 'me' => get_lang('Me'),
- 'user_id' => api_get_user_id(),
- 'items' => $chats
- );
- echo json_encode($return);
- exit;
- }
- /**
- * @param int $fromUserId
- * @param int $toUserId
- * @return mixed
- */
- public function getCountMessagesExchangeBetweenUsers($fromUserId, $toUserId)
- {
- $row = Database::select(
- 'count(*) as count',
- $this->table,
- array(
- 'where' => array(
- '(from_user = ? AND to_user = ?) OR (from_user = ? AND to_user = ?) ' => [
- $fromUserId,
- $toUserId,
- $toUserId,
- $fromUserId
- ]
- )
- ),
- 'first'
- );
- return $row['count'];
- }
- /**
- * @param int $fromUserId
- * @param int $toUserId
- * @param int $visibleMessages
- * @param int $previousMessageCount messages to show
- * @return array
- */
- public function getPreviousMessages(
- $fromUserId,
- $toUserId,
- $visibleMessages = 1,
- $previousMessageCount = 5
- ) {
- $currentUserId = api_get_user_id();
- $toUserId = (int) $toUserId;
- $fromUserId = (int) $fromUserId;
- $previousMessageCount = (int) $previousMessageCount;
- if (empty($toUserId) || empty($fromUserId)) {
- return [];
- }
- $total = self::getCountMessagesExchangeBetweenUsers(
- $fromUserId,
- $toUserId
- );
- $show = $total - $visibleMessages;
- $from = $show - $previousMessageCount;
- if ($from < 0) {
- return [];
- }
- $sql = "SELECT * FROM ".$this->table."
- WHERE
- (
- to_user = $toUserId AND
- from_user = $fromUserId)
- OR
- (
- from_user = $toUserId AND
- to_user = $fromUserId
- )
- ORDER BY id ASC
- LIMIT $from, $previousMessageCount
- ";
- $result = Database::query($sql);
- $rows = Database::store_result($result);
- $fromUserInfo = api_get_user_info($fromUserId, true);
- $toUserInfo = api_get_user_info($toUserId, true);
- $users = [
- $fromUserId => $fromUserInfo,
- $toUserId => $toUserInfo,
- ];
- $items = [];
- $rows = array_reverse($rows);
- foreach ($rows as $chat) {
- $fromUserId = $chat['from_user'];
- $userInfo = $users[$fromUserId];
- $username = $userInfo['complete_name'];
- if ($currentUserId == $fromUserId) {
- $username = get_lang('Me');
- }
- $chat['message'] = Security::remove_XSS($chat['message']);
- $item = array(
- 'id' => $chat['id'],
- 's' => '0',
- 'f' => $fromUserId,
- 'm' => $chat['message'],
- 'username' => $username,
- 'user_info' => [
- 'username' => $username,
- 'online' => $userInfo['user_is_online'],
- 'avatar' => $userInfo['avatar_small'],
- 'user_id' => $userInfo['user_id']
- ],
- 'date' => api_strtotime($chat['sent'], 'UTC')
- );
- $items[] = $item;
- $_SESSION['openChatBoxes'][$fromUserId] = api_strtotime($chat['sent'], 'UTC');
- }
- //array_unshift($_SESSION['chatHistory'][$fromUserId]['items'], $items);
- return $items;
- }
- /**
- * Refreshes the chat windows (usually called every x seconds through AJAX)
- * @return void (prints JSON array of chat windows)
- */
- public function heartbeat()
- {
- $to_user_id = api_get_user_id();
- $sql = "SELECT * FROM ".$this->table."
- WHERE to_user = '".intval($to_user_id)."' AND (recd = 0)
- ORDER BY id ASC";
- $result = Database::query($sql);
- $chat_list = array();
- while ($chat = Database::fetch_array($result, 'ASSOC')) {
- $chat_list[$chat['from_user']]['items'][] = $chat;
- }
- $items = array();
- foreach ($chat_list as $fromUserId => $rows) {
- $rows = $rows['items'];
- $user_info = api_get_user_info($fromUserId, true);
- $count = $this->getCountMessagesExchangeBetweenUsers(
- $fromUserId,
- $to_user_id
- );
- $chatItems = self::getLatestChat($fromUserId, $to_user_id, 5);
- // Cleaning tsChatBoxes
- unset($_SESSION['tsChatBoxes'][$fromUserId]);
- foreach ($rows as $chat) {
- /*$chat['message'] = Security::remove_XSS($chat['message']);
- $item = array(
- 's' => '0',
- 'f' => $fromUserId,
- 'm' => $chat['message'],
- 'username' => $user_info['complete_name'],
- 'date' => api_strtotime($chat['sent'], 'UTC'),
- 'id' => $chat['id']
- );
- $items[$fromUserId]['items'][] = $item;
- $items[$fromUserId]['total_messages'] = $count;
- $items[$fromUserId]['user_info']['user_name'] = $user_info['complete_name'];
- $items[$fromUserId]['user_info']['online'] = $user_info['user_is_online'];
- $items[$fromUserId]['user_info']['avatar'] = $user_info['avatar_small'];*/
- $_SESSION['openChatBoxes'][$fromUserId] = api_strtotime($chat['sent'], 'UTC');
- }
- $items[$fromUserId]['items'] = $chatItems;
- $items[$fromUserId]['total_messages'] = $count;
- $items[$fromUserId]['user_info']['user_name'] = $user_info['complete_name'];
- $items[$fromUserId]['user_info']['online'] = $user_info['user_is_online'];
- $items[$fromUserId]['user_info']['avatar'] = $user_info['avatar_small'];
- $items[$fromUserId]['user_info']['user_id'] = $user_info['user_id'];
- $_SESSION['chatHistory'][$fromUserId]['items'] = $chatItems;
- $_SESSION['chatHistory'][$fromUserId]['total_messages'] = $count;
- $_SESSION['chatHistory'][$fromUserId]['user_info']['user_id'] = $user_info['user_id'];
- $_SESSION['chatHistory'][$fromUserId]['user_info']['user_name'] = $user_info['complete_name'];
- $_SESSION['chatHistory'][$fromUserId]['user_info']['online'] = $user_info['user_is_online'];
- $_SESSION['chatHistory'][$fromUserId]['user_info']['avatar'] = $user_info['avatar_small'];
- }
- if (!empty($_SESSION['openChatBoxes'])) {
- foreach ($_SESSION['openChatBoxes'] as $user_id => $time) {
- if (!isset($_SESSION['tsChatBoxes'][$user_id])) {
- $now = time() - $time;
- $time = api_convert_and_format_date($time, DATE_TIME_FORMAT_SHORT_TIME_FIRST);
- $message = sprintf(get_lang('SentAtX'), $time);
- if ($now > 180) {
- $item = array(
- 's' => '2',
- 'f' => $user_id,
- 'm' => $message
- );
- if (isset($_SESSION['chatHistory'][$user_id])) {
- $_SESSION['chatHistory'][$user_id]['items'][] = $item;
- }
- $_SESSION['tsChatBoxes'][$user_id] = 1;
- }
- }
- }
- }
- $sql = "UPDATE ".$this->table."
- SET recd = 1
- WHERE to_user = '".$to_user_id."' AND recd = 0";
- Database::query($sql);
- echo json_encode(['items' => $items]);
- }
- /**
- * Returns an array of messages inside a chat session with a specific user
- * @param int The ID of the user with whom the current user is chatting
- * @return array Messages list
- */
- public function box_session($user_id)
- {
- $items = array();
- if (isset($_SESSION['chatHistory'][$user_id])) {
- $items = $_SESSION['chatHistory'][$user_id];
- }
- return $items;
- }
- /**
- * Saves into session the fact that a chat window exists with the given user
- * @param int The ID of the user with whom the current user is chatting
- * @param integer $user_id
- * @return void
- */
- public function save_window($user_id)
- {
- $this->window_list[$user_id] = true;
- Session::write('window_list', $this->window_list);
- }
- /**
- * Sends a message from one user to another user
- * @param int $fromUserId The ID of the user sending the message
- * @param int $to_user_id The ID of the user receiving the message
- * @param string $message Message
- * @param boolean $printResult Optional. Whether print the result
- * @param boolean $sanitize Optional. Whether sanitize the message
- *
- * @return void Prints "1"
- */
- public function send(
- $fromUserId,
- $to_user_id,
- $message,
- $printResult = true,
- $sanitize = true
- ) {
- $user_friend_relation = SocialManager::get_relation_between_contacts(
- $fromUserId,
- $to_user_id
- );
- if ($user_friend_relation == USER_RELATION_TYPE_FRIEND) {
- $now = api_get_utc_datetime();
- $user_info = api_get_user_info($to_user_id, true);
- $this->save_window($to_user_id);
- $_SESSION['openChatBoxes'][$to_user_id] = $now;
- if ($sanitize) {
- $messagesan = self::sanitize($message);
- } else {
- $messagesan = $message;
- }
- if (!isset($_SESSION['chatHistory'][$to_user_id])) {
- $_SESSION['chatHistory'][$to_user_id] = array();
- }
- $item = array(
- "s" => "1",
- "f" => $fromUserId,
- "m" => $messagesan,
- 'date' => api_strtotime($now, 'UTC'),
- 'username' => get_lang('Me')
- );
- $_SESSION['chatHistory'][$to_user_id]['items'][] = $item;
- $_SESSION['chatHistory'][$to_user_id]['user_info']['user_name'] = $user_info['complete_name'];
- $_SESSION['chatHistory'][$to_user_id]['user_info']['online'] = $user_info['user_is_online'];
- $_SESSION['chatHistory'][$to_user_id]['user_info']['avatar'] = $user_info['avatar_small'];
- $_SESSION['chatHistory'][$to_user_id]['user_info']['user_id'] = $user_info['user_id'];
- unset($_SESSION['tsChatBoxes'][$to_user_id]);
- $params = array();
- $params['from_user'] = intval($fromUserId);
- $params['to_user'] = intval($to_user_id);
- $params['message'] = $message;
- $params['sent'] = api_get_utc_datetime();
- if (!empty($fromUserId) && !empty($to_user_id)) {
- $this->save($params);
- }
- if ($printResult) {
- echo '1';
- exit;
- }
- } else {
- if ($printResult) {
- echo '0';
- exit;
- }
- }
- }
- /**
- * Close a specific chat box (user ID taken from $_POST['chatbox'])
- * @return void Prints "1"
- */
- public function close()
- {
- unset($_SESSION['openChatBoxes'][$_POST['chatbox']]);
- unset($_SESSION['chatHistory'][$_POST['chatbox']]);
- echo "1";
- exit;
- }
- /**
- * Filter chat messages to avoid XSS or other JS
- * @param string $text Unfiltered message
- *
- * @return string Filtered mssage
- */
- public function sanitize($text)
- {
- $text = htmlspecialchars($text, ENT_QUOTES);
- $text = str_replace("\n\r", "\n", $text);
- $text = str_replace("\r\n", "\n", $text);
- $text = str_replace("\n", "<br>", $text);
- return $text;
- }
- /**
- * SET Disable Chat
- * @param boolean $status to disable chat
- * @return void
- */
- public static function setDisableChat($status = true)
- {
- Session::write('disable_chat', $status);
- }
- /**
- * Disable Chat - disable the chat
- * @return boolean - return true if setDisableChat status is true
- */
- public static function disableChat()
- {
- $status = Session::read('disable_chat');
- if (!empty($status)) {
- if ($status == true) {
- Session::write('disable_chat', null);
- return true;
- }
- }
- return false;
- }
- /**
- * @return bool
- */
- public function is_chat_blocked_by_exercises()
- {
- $currentExercises = Session::read('current_exercises');
- if (!empty($currentExercises)) {
- foreach ($currentExercises as $attempt_status) {
- if ($attempt_status == true) {
- return true;
- }
- }
- }
- return false;
- }
- }
|