chat.lib.php 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317
  1. <?php
  2. /* For licensing terms, see /license.txt */
  3. /**
  4. * Class Chat
  5. *
  6. * @package chamilo.library.chat
  7. */
  8. class Chat extends Model
  9. {
  10. public $table;
  11. public $columns = array('id', 'from_user', 'to_user', 'message', 'sent', 'recd');
  12. public $window_list = array();
  13. /**
  14. * The contructor sets the chat table name and the window_list attribute
  15. * @return object Object reference
  16. */
  17. public function __construct()
  18. {
  19. $this->table = Database::get_main_table(TABLE_MAIN_CHAT);
  20. $this->window_list = $_SESSION['window_list'] = isset($_SESSION['window_list']) ? $_SESSION['window_list'] : array();
  21. }
  22. /**
  23. * Get user chat status
  24. * @return int 0 if disconnected, 1 if connected
  25. */
  26. function get_user_status()
  27. {
  28. $status = UserManager::get_extra_user_data_by_field(
  29. api_get_user_id(),
  30. 'user_chat_status',
  31. false,
  32. true
  33. );
  34. return $status['user_chat_status'];
  35. }
  36. /**
  37. * Set user chat status
  38. * @param int 0 if disconnected, 1 if connected
  39. * @param integer $status
  40. *
  41. * @return void
  42. */
  43. public function setUserStatus($status)
  44. {
  45. UserManager::update_extra_field_value(api_get_user_id(), 'user_chat_status', $status);
  46. }
  47. /**
  48. * Starts a chat session and returns JSON array of status and chat history
  49. * @return void (prints output in JSON format)
  50. */
  51. public function startSession()
  52. {
  53. $items = array();
  54. if (isset($_SESSION['chatHistory'])) {
  55. $items = $_SESSION['chatHistory'];
  56. }
  57. $return = array(
  58. 'user_status' => $this->get_user_status(),
  59. 'me' => get_lang('Me'),
  60. 'items' => $items
  61. );
  62. echo json_encode($return);
  63. exit;
  64. }
  65. /**
  66. * Refreshes the chat windows (usually called every x seconds through AJAX)
  67. * @return void (prints JSON array of chat windows)
  68. */
  69. public function heartbeat()
  70. {
  71. $to_user_id = api_get_user_id();
  72. $sql = "SELECT * FROM ".$this->table."
  73. WHERE to_user = '".intval($to_user_id)."' AND ( recd = 0 )
  74. ORDER BY id ASC";
  75. $result = Database::query($sql);
  76. $chat_list = array();
  77. while ($chat = Database::fetch_array($result, 'ASSOC')) {
  78. $chat_list[$chat['from_user']]['items'][] = $chat;
  79. }
  80. $items = array();
  81. foreach ($chat_list as $from_user_id => $rows) {
  82. $rows = $rows['items'];
  83. $user_info = api_get_user_info($from_user_id, true);
  84. //Cleaning tsChatBoxes
  85. unset($_SESSION['tsChatBoxes'][$from_user_id]);
  86. foreach ($rows as $chat) {
  87. $chat['message'] = Security::remove_XSS($chat['message']);
  88. $item = array('s' => '0',
  89. 'f' => $from_user_id,
  90. 'm' => $chat['message'],
  91. 'username' => $user_info['complete_name'],
  92. 'id' => $chat['id']
  93. );
  94. $items[$from_user_id]['items'][] = $item;
  95. $items[$from_user_id]['user_info']['user_name'] = $user_info['complete_name'];
  96. $items[$from_user_id]['user_info']['online'] = $user_info['user_is_online'];
  97. $items[$from_user_id]['user_info']['avatar'] = $user_info['avatar_small'];
  98. $_SESSION['openChatBoxes'][$from_user_id] = api_strtotime($chat['sent'], 'UTC');
  99. }
  100. $_SESSION['chatHistory'][$from_user_id]['items'][] = $item;
  101. $_SESSION['chatHistory'][$from_user_id]['user_info']['user_name'] = $user_info['complete_name'];
  102. $_SESSION['chatHistory'][$from_user_id]['user_info']['online'] = $user_info['user_is_online'];
  103. $_SESSION['chatHistory'][$from_user_id]['user_info']['avatar'] = $user_info['avatar_small'];
  104. }
  105. if (!empty($_SESSION['openChatBoxes'])) {
  106. foreach ($_SESSION['openChatBoxes'] as $user_id => $time) {
  107. if (!isset($_SESSION['tsChatBoxes'][$user_id])) {
  108. $now = time() - $time;
  109. $time = api_convert_and_format_date($time, DATE_TIME_FORMAT_SHORT_TIME_FIRST);
  110. $message = sprintf(get_lang('SentAtX'), $time);
  111. if ($now > 180) {
  112. $item = array('s' => '2', 'f' => $user_id, 'm' => $message);
  113. if (isset($_SESSION['chatHistory'][$user_id])) {
  114. $_SESSION['chatHistory'][$user_id]['items'][] = $item;
  115. }
  116. $_SESSION['tsChatBoxes'][$user_id] = 1;
  117. }
  118. }
  119. }
  120. }
  121. $sql = "UPDATE ".$this->table." SET recd = 1
  122. WHERE to_user = '".$to_user_id."' AND recd = 0";
  123. Database::query($sql);
  124. if ($items != '') {
  125. //$items = substr($items, 0, -1);
  126. }
  127. echo json_encode(array('items' => $items));
  128. }
  129. /**
  130. * Returns an array of messages inside a chat session with a specific user
  131. * @param int The ID of the user with whom the current user is chatting
  132. * @return array Messages list
  133. */
  134. public function box_session($user_id)
  135. {
  136. $items = array();
  137. if (isset($_SESSION['chatHistory'][$user_id])) {
  138. $items = $_SESSION['chatHistory'][$user_id];
  139. }
  140. return $items;
  141. }
  142. /**
  143. * Saves into session the fact that a chat window exists with the given user
  144. * @param int The ID of the user with whom the current user is chatting
  145. * @param integer $user_id
  146. * @return void
  147. */
  148. public function save_window($user_id)
  149. {
  150. $this->window_list[$user_id] = true;
  151. $_SESSION['window_list'] = $this->window_list;
  152. }
  153. /**
  154. * Sends a message from one user to another user
  155. * @param int $from_user_id The ID of the user sending the message
  156. * @param int $to_user_id The ID of the user receiving the message
  157. * @param string $message Message
  158. * @param boolean $printResult Optional. Whether print the result
  159. * @param boolean $sanitize Optional. Whether sanitize the message
  160. * @return void Prints "1"
  161. */
  162. public function send(
  163. $from_user_id,
  164. $to_user_id,
  165. $message,
  166. $printResult = true,
  167. $sanitize = true
  168. )
  169. {
  170. $user_friend_relation = SocialManager::get_relation_between_contacts(
  171. $from_user_id,
  172. $to_user_id
  173. );
  174. if ($user_friend_relation == USER_RELATION_TYPE_FRIEND) {
  175. $user_info = api_get_user_info($to_user_id, true);
  176. $this->save_window($to_user_id);
  177. $_SESSION['openChatBoxes'][$to_user_id] = api_get_utc_datetime();
  178. if ($sanitize) {
  179. $messagesan = self::sanitize($message);
  180. } else {
  181. $messagesan = $message;
  182. }
  183. error_log(print_r($sanitize) . '----' . $messagesan);
  184. if (!isset($_SESSION['chatHistory'][$to_user_id])) {
  185. $_SESSION['chatHistory'][$to_user_id] = array();
  186. }
  187. $item = array("s" => "1",
  188. "f" => $from_user_id,
  189. "m" => $messagesan,
  190. "username" => get_lang('Me')
  191. );
  192. $_SESSION['chatHistory'][$to_user_id]['items'][] = $item;
  193. $_SESSION['chatHistory'][$to_user_id]['user_info']['user_name'] = $user_info['complete_name'];
  194. $_SESSION['chatHistory'][$to_user_id]['user_info']['online'] = $user_info['user_is_online'];
  195. $_SESSION['chatHistory'][$to_user_id]['user_info']['avatar'] = $user_info['avatar_small'];
  196. unset($_SESSION['tsChatBoxes'][$to_user_id]);
  197. $params = array();
  198. $params['from_user'] = intval($from_user_id);
  199. $params['to_user'] = intval($to_user_id);
  200. $params['message'] = $message;
  201. $params['sent'] = api_get_utc_datetime();
  202. if (!empty($from_user_id) && !empty($to_user_id)) {
  203. $this->save($params);
  204. }
  205. if ($printResult) {
  206. echo "1";
  207. exit;
  208. }
  209. } else {
  210. if ($printResult) {
  211. echo "0";
  212. exit;
  213. }
  214. }
  215. }
  216. /**
  217. * Close a specific chat box (user ID taken from $_POST['chatbox'])
  218. * @return void Prints "1"
  219. */
  220. public function close()
  221. {
  222. unset($_SESSION['openChatBoxes'][$_POST['chatbox']]);
  223. unset($_SESSION['chatHistory'][$_POST['chatbox']]);
  224. echo "1";
  225. exit;
  226. }
  227. /**
  228. * Filter chat messages to avoid XSS or other JS
  229. * @param string $text Unfiltered message
  230. *
  231. * @return string Filterd mssage
  232. */
  233. public function sanitize($text)
  234. {
  235. $text = htmlspecialchars($text, ENT_QUOTES);
  236. $text = str_replace("\n\r", "\n", $text);
  237. $text = str_replace("\r\n", "\n", $text);
  238. $text = str_replace("\n", "<br>", $text);
  239. return $text;
  240. }
  241. /**
  242. * SET Disable Chat
  243. * @param boolean status to disable chat
  244. * @return void
  245. */
  246. public static function setDisableChat($status = true)
  247. {
  248. $_SESSION['disable_chat'] = $status;
  249. }
  250. /**
  251. * Disable Chat - disable the chat
  252. * @return boolean - return true if setDisableChat status is true
  253. */
  254. public static function disableChat()
  255. {
  256. if (!empty($_SESSION['disable_chat'])){
  257. $status = $_SESSION['disable_chat'];
  258. if ($status == true){
  259. $_SESSION['disable_chat'] = null;
  260. return true;
  261. }
  262. }
  263. return false;
  264. }
  265. public function is_chat_blocked_by_exercises()
  266. {
  267. if (isset($_SESSION['current_exercises'])) {
  268. foreach ($_SESSION['current_exercises'] as $attempt_status) {
  269. if ($attempt_status == true) {
  270. return true;
  271. }
  272. }
  273. }
  274. return false;
  275. }
  276. }