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.

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