messages_contacts.php 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400
  1. <?php
  2. /*
  3. FusionPBX
  4. Version: MPL 1.1
  5. The contents of this file are subject to the Mozilla Public License Version
  6. 1.1 (the "License"); you may not use this file except in compliance with
  7. the License. You may obtain a copy of the License at
  8. http://www.mozilla.org/MPL/
  9. Software distributed under the License is distributed on an "AS IS" basis,
  10. WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
  11. for the specific language governing rights and limitations under the
  12. License.
  13. The Original Code is FusionPBX
  14. The Initial Developer of the Original Code is
  15. Mark J Crane <[email protected]>
  16. Portions created by the Initial Developer are Copyright (C) 2023
  17. the Initial Developer. All Rights Reserved.
  18. Contributor(s):
  19. Mark J Crane <[email protected]>
  20. */
  21. //includes files
  22. require_once dirname(__DIR__, 2) . "/resources/require.php";
  23. require_once "resources/check_auth.php";
  24. //check permissions
  25. if (!permission_exists('message_view')) {
  26. echo "access denied";
  27. exit;
  28. }
  29. //add multi-lingual support
  30. $language = new text;
  31. $text = $language->get();
  32. //get selected number/contact
  33. if (isset($_GET['number']) && !empty($_GET['number'])) {
  34. $_SESSION['user']['contact_number'] = $_GET['number'];
  35. }
  36. //build a list of groups the user is a member of to be used in a SQL in
  37. foreach($_SESSION['user']['groups'] as $group) {
  38. if (is_uuid($group['group_uuid'])) {
  39. $group_uuids[] = $group['group_uuid'];
  40. }
  41. }
  42. $group_uuids_in = "'".implode("','", $group_uuids)."'";
  43. //get the list of contacts
  44. $sql = "select *, \n";
  45. $sql .= "(\n";
  46. $sql .= " (select effective_caller_id_name as name from v_extensions where n.number = extension limit 1)\n";
  47. $sql .= " union\n";
  48. $sql .= " (select concat_ws(' ', contact_name_given, contact_name_family) as name from v_contacts where contact_uuid in (select contact_uuid from v_contact_phones where n.number = phone_number) limit 1)\n";
  49. $sql .= ") as name,\n";
  50. $sql .= "(\n";
  51. $sql .= " select contact_uuid from v_contact_phones where n.number = phone_number limit 1\n";
  52. $sql .= ") as contact_uuid,\n";
  53. $sql .= "(\n";
  54. $sql .= " select attachment_filename from v_contact_attachments where contact_uuid in (select contact_uuid from v_contact_phones where n.number = phone_number)\n";
  55. $sql .= ") as contact_image_filename,\n";
  56. $sql .= "(\n";
  57. $sql .= " select attachment_content from v_contact_attachments where contact_uuid in (select contact_uuid from v_contact_phones where n.number = phone_number)\n";
  58. $sql .= ") as contact_image_content,\n";
  59. $sql .= "(\n";
  60. $sql .= " select count(*) as count from v_messages where message_read is not true and message_direction = 'inbound' and message_from = n.number\n";
  61. $sql .= ") as count,\n";
  62. $sql .= "(\n";
  63. $sql .= " select message_text from v_messages\n";
  64. $sql .= " where \n";
  65. $sql .= " (\n";
  66. $sql .= " (message_direction = 'inbound' and message_from = n.number)\n";
  67. $sql .= " or \n";
  68. $sql .= " (message_direction = 'outbound' and message_to = n.number)\n";
  69. $sql .= " )\n";
  70. $sql .= " and message_text is not null\n";
  71. $sql .= " order by message_date desc limit 1\n";
  72. $sql .= ") as message,\n";
  73. $sql .= "(\n";
  74. $sql .= " select message_date from v_messages \n";
  75. $sql .= " where (\n";
  76. $sql .= " (message_direction = 'inbound' and message_from = n.number)\n";
  77. $sql .= " or \n";
  78. $sql .= " (message_direction = 'outbound' and message_to = n.number)\n";
  79. $sql .= " )\n";
  80. $sql .= " and message_text is not null\n";
  81. $sql .= " order by message_date desc limit 1\n";
  82. $sql .= ") as date\n";
  83. $sql .= "from (\n";
  84. $sql .= " select number from \n";
  85. $sql .= " (\n";
  86. $sql .= " select distinct(message_from) as number from v_messages \n";
  87. $sql .= " where domain_uuid = :domain_uuid \n";
  88. $sql .= " and message_direction = 'inbound' and message_from is not null \n";
  89. //$sql .= " and user_uuid = :user_uuid \n";
  90. $sql .= " and ( \n";
  91. $sql .= " user_uuid = :user_uuid \n";
  92. $sql .= " or \n";
  93. $sql .= " group_uuid in (\n";
  94. $sql .= " select group_uuid from v_destinations \n";
  95. $sql .= " where group_uuid in (".$group_uuids_in.") \n";
  96. $sql .= " and domain_uuid = :domain_uuid \n";
  97. $sql .= " ) \n";
  98. $sql .= " )\n";
  99. $sql .= " and message_from ~'^\+?([0-9]+\.?[0-9]*|\.[0-9]+)$' \n";
  100. $sql .= " union \n";
  101. $sql .= " select distinct(message_to) as number from v_messages \n";
  102. $sql .= " where domain_uuid = :domain_uuid \n";
  103. $sql .= " and message_direction = 'outbound' and message_from is not null \n";
  104. //$sql .= " and user_uuid = :user_uuid ";
  105. $sql .= " and ( \n";
  106. $sql .= " user_uuid = :user_uuid \n";
  107. $sql .= " or \n";
  108. $sql .= " group_uuid in (\n";
  109. $sql .= " select group_uuid from v_destinations \n";
  110. $sql .= " where group_uuid in (".$group_uuids_in.") \n";
  111. $sql .= " and domain_uuid = :domain_uuid \n";
  112. $sql .= " ) \n";
  113. $sql .= " ) \n";
  114. $sql .= " and message_to ~'^\+?([0-9]+\.?[0-9]*|\.[0-9]+)$' \n";
  115. $sql .= " ) as nested \n";
  116. $sql .= " where number not in \n";
  117. $sql .= " ( \n";
  118. $sql .= " select destination_number as number \n";
  119. $sql .= " from v_destinations \n";
  120. $sql .= " where destination_type = 'inbound' \n";
  121. $sql .= " and domain_uuid = :domain_uuid \n";
  122. $sql .= " union \n";
  123. $sql .= " select (concat(destination_prefix, destination_number)) as number \n";
  124. $sql .= " from v_destinations \n";
  125. $sql .= " where destination_type = 'inbound' \n";
  126. $sql .= " and domain_uuid = :domain_uuid \n";
  127. $sql .= " ) \n";
  128. $sql .= " order by number asc\n";
  129. $sql .= ") as n\n";
  130. $sql .= "order by \n";
  131. $sql .= "case when (number = :number) then 0 end asc,\n";
  132. $sql .= "date desc\n";
  133. $parameters['domain_uuid'] = $domain_uuid;
  134. $parameters['user_uuid'] = $_SESSION['user']['user_uuid'];
  135. $parameters['number'] = $_SESSION['user']['contact_number'] ?? null;
  136. //echo "<pre>\n";
  137. //echo $sql;
  138. //echo "</pre>\n";
  139. //view_array($parameters);
  140. $database = new database;
  141. $contacts = $database->select($sql, $parameters, 'all');
  142. //view_array($contacts);
  143. unset($sql, $parameters);
  144. //show the content
  145. echo "<!DOCTYPE html>\n";
  146. echo "<html>\n";
  147. echo "<head>\n";
  148. //include icons
  149. echo "<link rel='stylesheet' type='text/css' href='/resources/fontawesome/css/all.min.css.php'>\n";
  150. echo "<script language='JavaScript' type='text/javascript' src='/resources/fontawesome/js/solid.min.js.php' defer></script>\n";
  151. //js to load messages for clicked number
  152. echo "<script>\n";
  153. //scroll to the bottom
  154. echo " function scroll_to_bottom(id) {\n";
  155. echo " parent.document.getElementById(id).contentWindow.scrollTo(0, 999999);\n";
  156. echo " }\n";
  157. echo "\n";
  158. //update the url
  159. echo " function update_url(id, url) {\n";
  160. //echo " alert('from: '+parent.document.getElementById('message_from').value);\n";
  161. //echo " alert('to: '+parent.document.getElementById('message_to').value);\n";
  162. //echo " alert('to: '+parent.document.getElementById('message_text').value);\n";
  163. echo " parent.document.getElementById(id).onload = function() {\n";
  164. // echo " scroll_to_bottom(id);\n";
  165. echo " this.contentWindow.scrollTo(0, 999999);\n";
  166. echo " }\n";
  167. echo " parent.document.getElementById(id).src = url;\n";
  168. //echo " scroll_to_bottom(id);\n";
  169. echo " }\n";
  170. echo "</script>\n";
  171. //styles
  172. echo "<style>\n";
  173. echo "\n";
  174. echo " body {\n";
  175. echo " margin: 0 14px 0 0;\n";
  176. echo " }\n";
  177. echo " #message_new_layer {\n";
  178. echo " z-index: 999999;\n";
  179. echo " position: absolute;\n";
  180. echo " left: 0px;\n";
  181. echo " top: 0px;\n";
  182. echo " right: 0px;\n";
  183. echo " bottom: 0px;\n";
  184. echo " text-align: center;\n";
  185. echo " vertical-align: middle;\n";
  186. echo " }\n";
  187. echo "\n";
  188. echo " #message_new_container {\n";
  189. echo " display: block;\n";
  190. echo " background-color: #fff;\n";
  191. echo " padding: 20px 30px;\n";
  192. if (http_user_agent('mobile')) {
  193. echo " margin: 0;\n";
  194. }
  195. else {
  196. echo " margin: auto 30%;\n";
  197. }
  198. echo " text-align: left;\n";
  199. echo " -webkit-box-shadow: 0px 1px 20px #888;\n";
  200. echo " -moz-box-shadow: 0px 1px 20px #888;\n";
  201. echo " box-shadow: 0px 1px 20px #888;\n";
  202. echo " }\n";
  203. echo "\n";
  204. echo " #message_media_layer {\n";
  205. echo " z-index: 999999;\n";
  206. echo " position: absolute;\n";
  207. echo " left: 0px;\n";
  208. echo " top: 0px;\n";
  209. echo " right: 0px;\n";
  210. echo " bottom: 0px;\n";
  211. echo " text-align: center;\n";
  212. echo " vertical-align: middle;\n";
  213. echo " }\n";
  214. echo "\n";
  215. echo " td.contact_selected {\n";
  216. echo " border-right: 5px solid ".($_SESSION['theme']['message_bubble_em_border_color']['text'] ?? '#abefa0').";\n";
  217. echo " }\n";
  218. echo "\n";
  219. echo " .contact_list_image {\n";
  220. echo " float: left;\n";
  221. echo " width: 75px;\n";
  222. echo " height: 75px;\n";
  223. echo " margin: 3px 8px 3px 2px;\n";
  224. echo " border: 1px solid ".($_SESSION['theme']['table_row_border_color']['text'] ?? '#c5d1e5').";\n";
  225. echo " background-repeat: no-repeat;\n";
  226. echo " background-size: cover;\n";
  227. echo " background-position: center center;\n";
  228. echo " border-radius: 11px;\n";
  229. echo " }\n";
  230. echo "\n";
  231. echo " .row_style0 {\n";
  232. echo " border-top: 1px solid ".($_SESSION['theme']['message_bubble_em_border_color']['text'] ?? '#abefa0').";\n";
  233. echo " border-bottom: 1px solid ".($_SESSION['theme']['message_bubble_em_border_color']['text'] ?? '#abefa0').";\n";
  234. echo " border-radius: 4px;\n";
  235. echo " background: ".($_SESSION['theme']['message_bubble_em_background_color']['text'] ?? '#daffd4').";\n";
  236. echo " color: ".($_SESSION['theme']['body_text_color']['text'] ?? '#5f5f5f').";\n";
  237. echo " font-family: ".($_SESSION['theme']['body_text_font']['text'] ?? 'arial').";\n";
  238. echo " font-size: 12px;\n";
  239. echo " text-align: left;\n";
  240. echo " padding: 4px 7px;\n";
  241. echo " padding-top: 8px;\n";
  242. echo " cursor: pointer;\n";
  243. echo " }\n";
  244. echo "\n";
  245. echo " .row_style1 {\n";
  246. echo " border-bottom: 1px solid ".($_SESSION['theme']['table_row_border_color']['text'] ?? '#c5d1e5').";\n";
  247. echo " border-radius: 4px;\n";
  248. echo " color: ".($_SESSION['theme']['body_text_color']['text'] ?? '#5f5f5f').";\n";
  249. echo " font-family: ".($_SESSION['theme']['body_text_font']['text'] ?? 'arial').";\n";
  250. echo " font-size: 12px;\n";
  251. echo " text-align: left;\n";
  252. echo " padding: 4px 7px;\n";
  253. echo " padding-top: 8px;\n";
  254. echo " cursor: pointer;\n";
  255. echo " }\n";
  256. echo "\n";
  257. echo " .contact_message {\n";
  258. echo " margin-top: 5px;\n";
  259. echo " padding-left: 5px;\n";
  260. echo " }\n";
  261. echo " @media (max-width: 121px) {\n";
  262. echo " .contact_message {\n";
  263. echo " display: none;\n";
  264. echo " }\n";
  265. echo " .contact_image {\n";
  266. echo " float: none;\n";
  267. echo " margin-left: 20.5%;\n";
  268. echo " }\n";
  269. echo " .row_style0, .row_style1 {\n";
  270. echo " padding-bottom: 0px;\n";
  271. echo " text-align: center;\n";
  272. echo " }\n";
  273. echo " }\n";
  274. echo "</style>\n";
  275. //end the header and start the body
  276. echo "</head>\n";
  277. echo "<body>\n";
  278. //contacts list
  279. if (!empty($contacts) && @sizeof($contacts) != 0) {
  280. echo "<table class='tr_hover' width='100%' border='0' cellpadding='0' cellspacing='0'>\n";
  281. foreach ($contacts as $row) {
  282. $number = $row['number'];
  283. $name = $row['name'];
  284. $count = $row['count'];
  285. $message = $row['message'];
  286. $date = $row['date'];
  287. // $row['contact_image_content'];
  288. // $row['contact_image_filename'];
  289. // $row['contact_uuid'];
  290. //get the image file extension
  291. if (!empty($row['contact_image_filename'])) {
  292. $contact_image_extension = pathinfo($row['contact_image_filename'], PATHINFO_EXTENSION);
  293. }
  294. //set the count label
  295. if ($count == 0) {
  296. $count = '';
  297. }
  298. else {
  299. $count = ' ('.$count.')';
  300. }
  301. //$contact_name = format_phone($row['number']);
  302. $contact_name = $row['number'];
  303. if (!empty($row['name'])) {
  304. $contact_name = escape($row['name']);
  305. }
  306. if (!empty($_SESSION['user']['contact_number']) && $_SESSION['user']['contact_number'] == $number) {
  307. echo "<tr onclick=\"parent.document.getElementById('message_to').value=".escape($number)."; parent.document.getElementById('contacts_frame').src='messages_contacts.php?number=".urlencode($number)."'; update_url('messages_frame', 'messages_thread.php?number=".urlencode($number)."'); ".(permission_exists('contact_view') && !empty($_SESSION['message']['contact_details']['boolean']) && $_SESSION['message']['contact_details']['boolean'] == 'true' ? "parent.document.getElementById('contact_frame').src='message_contact.php?id=".$row['contact_uuid']."';" : null)."\"><td valign='top' class='row_style0 contact_selected'>\n";
  308. if (permission_exists('contact_view') && !empty($_SESSION['message']['contact_details']['boolean']) && $_SESSION['message']['contact_details']['boolean'] == 'true') {
  309. echo "<script>parent.document.getElementById('contact_frame').src='message_contact.php?destination=".urlencode($number)."&id=".$row['contact_uuid']."';</script>";
  310. }
  311. $selected = true;
  312. }
  313. else {
  314. echo "<tr onclick=\"parent.document.getElementById('message_to').value=".escape($number)."; parent.document.getElementById('contacts_frame').src='messages_contacts.php?number=".urlencode($number)."'; update_url('messages_frame', 'messages_thread.php?number=".urlencode($number)."'); ".(permission_exists('contact_view') && !empty($_SESSION['message']['contact_details']['boolean']) && $_SESSION['message']['contact_details']['boolean'] == 'true' ? "parent.document.getElementById('contact_frame').src='message_contact.php';" : null)."\"><td valign='top' class='row_style1'>\n"; // onclick=\"load_thread('".urlencode($number)."', '".$contact[$number]['contact_uuid']."');\"
  315. $selected = false;
  316. }
  317. if (!empty($row['contact_image_filename'])) {
  318. //echo "<img id='src_message-bubble-image-em_".$row['contact_uuid']."' style='display: none;' src='data:image/".$contact_image_extension.";base64,".$row['contact_image_content']."'>\n";
  319. echo "<div class='contact_image' style='width: 50px; height: 50px; float: left; padding-right: 3px;'>\n";
  320. echo " <img id='src_message-bubble-image-em_".$row['contact_uuid']."' src=\"data:image/png;base64,".$row['contact_image_content']."\" style=\"width: 50px;\">\n";
  321. echo "</div>\n";
  322. //echo "<img id='contact_image_".$row['contact_uuid']."' class='contact_list_image' src='data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7'>\n";
  323. }
  324. else {
  325. echo "<div class='contact_image' style='width: 50px; height: 50px; float: left; padding-right: 3px;'>\n";
  326. echo " <i class='fas fa-".(!empty($contact_name) && !is_numeric($contact_name) ? 'user-tie' : 'user')." fa-fw fa-3x' style='margin-top: 4px; color: ".($selected ? ($_SESSION['theme']['message_bubble_em_when_color']['text'] ?? '#52b342') : '#ccc').";'></i>\n";
  327. echo "</div>\n";
  328. }
  329. echo "<div style='padding-left: 3px; margin-bottom: 4px;'>\n";
  330. echo " <a href='view:messages' onclick='event.preventDefault();' style='text-decoration: none; color: ".($_SESSION['theme']['text_link_color']['text'] ?? '#004083').";'>\n";
  331. echo " <strong>".(is_numeric($contact_name) ? format_phone($contact_name) : escape($contact_name))."</strong>".$count."<br />\n";
  332. echo " </a>\n";
  333. echo " <div class='contact_message'>\n";
  334. echo " ".(!empty($message) && strlen($message) <= 100 ? escape($message) : substr($message,0,100).'...')."<br />\n";
  335. echo " </div>\n";
  336. echo "</div>\n";
  337. //if ($selected) {
  338. // echo "<script>$('#contact_current_name').html(\"<a href='callto:".escape($number)."'>".escape(format_phone($number))."</a>\");</script>\n";
  339. //}
  340. echo "</td></tr>\n";
  341. }
  342. echo "</table>\n";
  343. //echo "<script>\n";
  344. //foreach ($numbers as $number) {
  345. // if (is_array($_SESSION['tmp']['messages']['contact_em'][$contact[$number]['contact_uuid']]) && @sizeof($_SESSION['tmp']['messages']['contact_em'][$contact[$number]['contact_uuid']]) != 0) {
  346. // echo "$('img#contact_image_".$contact[$number]['contact_uuid']."').css('backgroundImage', 'url(' + $('img#src_message-bubble-image-em_".$contact[$number]['contact_uuid']."').attr('src') + ')');\n";
  347. // }
  348. //}
  349. //echo "</script>\n";
  350. }
  351. else {
  352. echo "<div style='padding: 15px;'><center>&middot;&middot;&middot;</center>";
  353. }
  354. echo "</body>\n";
  355. //echo "<center>\n";
  356. //echo " <span id='contacts_refresh_state'><img src='resources/images/refresh_active.gif' style='width: 16px; height: 16px; border: none; margin-top: 3px; cursor: pointer;' onclick=\"refresh_contacts_stop();\" alt=\"".$text['label-refresh_pause']."\" title=\"".$text['label-refresh_pause']."\"></span> ";
  357. //echo "</center>\n";
  358. echo "</html>\n";
  359. ?>