chat.lib.php 10 KB

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