You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

371 lines
9.3 KiB

  1. <?php
  2. use Moxl\Xec\Action\Message\Composing;
  3. use Moxl\Xec\Action\Message\Paused;
  4. use Moxl\Xec\Action\Message\Publish;
  5. class Chat extends WidgetCommon
  6. {
  7. function load()
  8. {
  9. $this->addjs('chat.js');
  10. $this->addjs('chat_otr.js');
  11. $this->addcss('chat.css');
  12. $this->registerEvent('carbons', 'onMessage');
  13. $this->registerEvent('message', 'onMessage');
  14. $this->registerEvent('composing', 'onComposing');
  15. $this->registerEvent('paused', 'onPaused');
  16. $this->registerEvent('gone', 'onGone');
  17. //$this->registerEvent('presence', 'onPresence');
  18. }
  19. /*
  20. * Disabled for the moment, it SPAM a bit too much the user
  21. function onPresence($packet)
  22. {
  23. $contacts = $packet->content;
  24. if($contacts != null){
  25. $contact = $contacts[0];
  26. if($contact->value < 5) {
  27. $avatar = $contact->getPhoto('s');
  28. if($avatar == false) $avatar = null;
  29. $presences = getPresences();
  30. $presence = $presences[$contact->value];
  31. Notification::append('presence', $contact->getTrueName(), $presence, $avatar, 4);
  32. }
  33. }
  34. }*/
  35. function onMessage($packet, $mine = false)
  36. {
  37. $message = $packet->content;
  38. $cd = new \Modl\ContactDAO;
  39. if($message->session == $message->jidto) {
  40. $from = $message->jidfrom;
  41. $contact = $cd->getRosterItem($from);
  42. if($contact == null)
  43. $contact = $cd->get($from);
  44. if($contact != null
  45. && !preg_match('#^\?OTR#', $message->body)
  46. && $message->type != 'groupchat') {
  47. $avatar = $contact->getPhoto('s');
  48. if($avatar == false) $avatar = null;
  49. Notification::append('chat|'.$from, $contact->getTrueName(), $message->body, $avatar, 4);
  50. }
  51. RPC::call('movim_fill', $from.'_state', '');
  52. // If the message is from me
  53. } else {
  54. $from = $message->jidto;
  55. $contact = $cd->get();
  56. }
  57. $me = $cd->get();
  58. if($me == null) {
  59. $me = new \Modl\Contact;
  60. }
  61. if(preg_match('#^\?OTR#', $message->body)) {
  62. if(!$mine) {
  63. //RPC::call('ChatOTR.receiveMessage', $message->body);
  64. }
  65. } else {
  66. RPC::call('Chat.appendMessage', $this->prepareMessage($message));
  67. }
  68. RPC::call('MovimTpl.scrollPanel');
  69. }
  70. function onComposing($array)
  71. {
  72. $this->setState($array, $this->__('message.composing'));
  73. }
  74. function onPaused($array)
  75. {
  76. $this->setState($array, $this->__('message.paused'));
  77. }
  78. function onGone($array)
  79. {
  80. $this->setState($array, $this->__('message.gone'));
  81. }
  82. private function setState($array, $message)
  83. {
  84. list($from, $to) = $array;
  85. if($from == $this->user->getLogin()) {
  86. $jid = $to;
  87. } else {
  88. $jid = $from;
  89. }
  90. $view = $this->tpl();
  91. $view->assign('message', $message);
  92. $html = $view->draw('_chat_state', true);
  93. RPC::call('movim_fill', $jid.'_state', $html);
  94. RPC::call('MovimTpl.scrollPanel');
  95. }
  96. /**
  97. * @brief Show the smiley list
  98. */
  99. function ajaxSmiley()
  100. {
  101. $view = $this->tpl();
  102. Dialog::fill($view->draw('_chat_smiley', true));
  103. }
  104. /**
  105. * @brief Get the path of a emoji
  106. */
  107. function ajaxSmileyGet($string)
  108. {
  109. return prepareString($string, true);
  110. }
  111. /**
  112. * @brief Get a discussion
  113. * @parem string $jid
  114. */
  115. function ajaxGet($jid = null)
  116. {
  117. if($jid == null) {
  118. RPC::call('movim_fill', 'chat_widget', $this->prepareEmpty());
  119. } else {
  120. $html = $this->prepareChat($jid);
  121. $header = $this->prepareHeader($jid);
  122. Header::fill($header);
  123. RPC::call('movim_fill', 'chat_widget', $html);
  124. RPC::call('MovimTpl.scrollPanel');
  125. RPC::call('MovimTpl.showPanel');
  126. $this->prepareMessages($jid);
  127. }
  128. }
  129. /**
  130. * @brief Get a chatroom
  131. * @parem string $jid
  132. */
  133. function ajaxGetRoom($room)
  134. {
  135. $html = $this->prepareChat($room, true);
  136. $header = $this->prepareHeaderRoom($room);
  137. Header::fill($header);
  138. RPC::call('movim_fill', 'chat_widget', $html);
  139. RPC::call('MovimTpl.scrollPanel');
  140. RPC::call('MovimTpl.showPanel');
  141. $this->prepareMessages($room, true);
  142. }
  143. /**
  144. * @brief Send a message
  145. *
  146. * @param string $to
  147. * @param string $message
  148. * @return void
  149. */
  150. function ajaxSendMessage($to, $message, $muc = false, $resource = false) {
  151. if($message == '')
  152. return;
  153. $m = new \Modl\Message();
  154. $m->session = $this->user->getLogin();
  155. $m->jidto = echapJid($to);
  156. $m->jidfrom = $this->user->getLogin();
  157. $session = \Sessionx::start();
  158. $m->type = 'chat';
  159. $m->resource = $session->resource;
  160. if($muc) {
  161. $m->type = 'groupchat';
  162. $m->resource = $session->user;
  163. $m->jidfrom = $to;
  164. }
  165. $m->body = rawurldecode($message);
  166. $m->published = date('Y-m-d H:i:s');
  167. $m->delivered = date('Y-m-d H:i:s');
  168. if(!preg_match('#^\?OTR#', $m->body)) {
  169. $md = new \Modl\MessageDAO();
  170. $md->set($m);
  171. }
  172. /* Is it really clean ? */
  173. $packet = new Moxl\Xec\Payload\Packet;
  174. $packet->content = $m;
  175. $this->onMessage($packet, true);
  176. if($resource != false) {
  177. $to = $to . '/' . $resource;
  178. }
  179. // We decode URL codes to send the correct message to the XMPP server
  180. $m = new Publish;
  181. $m->setTo($to);
  182. $m->setContent(htmlspecialchars(rawurldecode($message)));
  183. if($muc) {
  184. $m->setMuc();
  185. }
  186. $m->request();
  187. }
  188. /**
  189. * @brief Send a "composing" message
  190. *
  191. * @param string $to
  192. * @return void
  193. */
  194. function ajaxSendComposing($to) {
  195. $mc = new Composing;
  196. $mc->setTo($to)->request();
  197. }
  198. /**
  199. * @brief Send a "paused" message
  200. *
  201. * @param string $to
  202. * @return void
  203. */
  204. function ajaxSendPaused($to) {
  205. $mp = new Paused;
  206. $mp->setTo($to)->request();
  207. }
  208. /**
  209. * @brief Prepare the contact header
  210. *
  211. * @param string $jid
  212. */
  213. function prepareHeader($jid)
  214. {
  215. $view = $this->tpl();
  216. $cd = new \Modl\ContactDAO;
  217. $cr = $cd->getRosterItem($jid);
  218. if(isset($cr)) {
  219. $contact = $cr;
  220. } else {
  221. $contact = $cd->get($jid);
  222. }
  223. $view->assign('contact', $contact);
  224. $view->assign('jid', $jid);
  225. return $view->draw('_chat_header', true);
  226. }
  227. /**
  228. * @brief Prepare the contact header
  229. *
  230. * @param string $jid
  231. */
  232. function prepareHeaderRoom($room)
  233. {
  234. $view = $this->tpl();
  235. $view->assign('room', $room);
  236. return $view->draw('_chat_header_room', true);
  237. }
  238. function prepareChat($jid, $muc = false)
  239. {
  240. $view = $this->tpl();
  241. $view->assign('jid', $jid);
  242. $jid = echapJS($jid);
  243. $view->assign('composing', $this->call('ajaxSendComposing', "'" . $jid . "'"));
  244. $view->assign('paused', $this->call('ajaxSendPaused', "'" . $jid . "'"));
  245. $view->assign('smiley', $this->call('ajaxSmiley'));
  246. $view->assign('emoji', prepareString('😀'));
  247. $view->assign('muc', $muc);
  248. return $view->draw('_chat', true);
  249. }
  250. function prepareMessages($jid)
  251. {
  252. $md = new \Modl\MessageDAO();
  253. $messages = $md->getContact(echapJid($jid), 0, 30);
  254. $messages = array_reverse($messages);
  255. foreach($messages as $message) {
  256. $this->prepareMessage($message);
  257. }
  258. $view = $this->tpl();
  259. $view->assign('jid', $jid);
  260. $cd = new \Modl\ContactDAO;
  261. $contact = $cd->get($jid);
  262. $me = $cd->get();
  263. if($me == null) {
  264. $me = new \Modl\Contact;
  265. }
  266. $view->assign('contact', $contact);
  267. $view->assign('me', false);
  268. $left = $view->draw('_chat_bubble', true);
  269. $view->assign('contact', $me);
  270. $view->assign('me', true);
  271. $right = $view->draw('_chat_bubble', true);
  272. $room = $view->draw('_chat_bubble_room', true);
  273. RPC::call('Chat.setBubbles', $left, $right, $room);
  274. RPC::call('Chat.appendMessages', $messages);
  275. }
  276. function prepareMessage(&$message)
  277. {
  278. if(isset($message->html)) {
  279. $message->body = prepareString($message->html);
  280. } else {
  281. $message->body = prepareString(htmlentities($message->body , ENT_COMPAT,'UTF-8'));
  282. }
  283. if($message->type == 'groupchat') {
  284. $message->color = stringToColor($message->jidfrom.$message->resource);
  285. }
  286. $message->published = prepareDate(strtotime($message->published));
  287. return $message;
  288. }
  289. function prepareEmpty()
  290. {
  291. $view = $this->tpl();
  292. return $view->draw('_chat_empty', true);
  293. }
  294. function display()
  295. {
  296. }
  297. }