Friendica Communications Platform (please note that this is a clone of the repository at github, issues are handled there) https://friendi.ca
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.

595 lines
17 KiB

11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
10 years ago
10 years ago
10 years ago
11 years ago
11 years ago
  1. <?php
  2. require_once('include/acl_selectors.php');
  3. require_once('include/message.php');
  4. function message_init(&$a) {
  5. $tabs = '';
  6. if ($a->argc >1 && is_numeric($a->argv[1])) {
  7. $tabs = render_messages(get_messages(local_user(),0,5), 'mail_list.tpl');
  8. }
  9. $new = array(
  10. 'label' => t('New Message'),
  11. 'url' => $a->get_baseurl(true) . '/message/new',
  12. 'sel'=> ($a->argv[1] == 'new'),
  13. 'accesskey' => 'm',
  14. );
  15. $tpl = get_markup_template('message_side.tpl');
  16. $a->page['aside'] = replace_macros($tpl, array(
  17. '$tabs'=>$tabs,
  18. '$new'=>$new,
  19. ));
  20. $base = $a->get_baseurl();
  21. $head_tpl = get_markup_template('message-head.tpl');
  22. $a->page['htmlhead'] .= replace_macros($head_tpl,array(
  23. '$baseurl' => $a->get_baseurl(true),
  24. '$base' => $base
  25. ));
  26. $end_tpl = get_markup_template('message-end.tpl');
  27. $a->page['end'] .= replace_macros($end_tpl,array(
  28. '$baseurl' => $a->get_baseurl(true),
  29. '$base' => $base
  30. ));
  31. }
  32. function message_post(&$a) {
  33. if(! local_user()) {
  34. notice( t('Permission denied.') . EOL);
  35. return;
  36. }
  37. $replyto = ((x($_REQUEST,'replyto')) ? notags(trim($_REQUEST['replyto'])) : '');
  38. $subject = ((x($_REQUEST,'subject')) ? notags(trim($_REQUEST['subject'])) : '');
  39. $body = ((x($_REQUEST,'body')) ? escape_tags(trim($_REQUEST['body'])) : '');
  40. $recipient = ((x($_REQUEST,'messageto')) ? intval($_REQUEST['messageto']) : 0 );
  41. // Work around doubled linefeeds in Tinymce 3.5b2
  42. /* $plaintext = intval(get_pconfig(local_user(),'system','plaintext') && !feature_enabled(local_user(),'richtext'));
  43. if(! $plaintext) {
  44. $body = fix_mce_lf($body);
  45. }*/
  46. $plaintext = intval(!feature_enabled(local_user(),'richtext'));
  47. if(! $plaintext) {
  48. $body = fix_mce_lf($body);
  49. }
  50. $ret = send_message($recipient, $body, $subject, $replyto);
  51. $norecip = false;
  52. switch($ret){
  53. case -1:
  54. notice( t('No recipient selected.') . EOL );
  55. $norecip = true;
  56. break;
  57. case -2:
  58. notice( t('Unable to locate contact information.') . EOL );
  59. break;
  60. case -3:
  61. notice( t('Message could not be sent.') . EOL );
  62. break;
  63. case -4:
  64. notice( t('Message collection failure.') . EOL );
  65. break;
  66. default:
  67. info( t('Message sent.') . EOL );
  68. }
  69. // fake it to go back to the input form if no recipient listed
  70. if($norecip) {
  71. $a->argc = 2;
  72. $a->argv[1] = 'new';
  73. }
  74. else
  75. goaway($a->get_baseurl(true) . '/' . $_SESSION['return_url']);
  76. }
  77. // Note: the code in 'item_extract_images' and 'item_redir_and_replace_images'
  78. // is identical to the code in include/conversation.php
  79. if(! function_exists('item_extract_images')) {
  80. function item_extract_images($body) {
  81. $saved_image = array();
  82. $orig_body = $body;
  83. $new_body = '';
  84. $cnt = 0;
  85. $img_start = strpos($orig_body, '[img');
  86. $img_st_close = ($img_start !== false ? strpos(substr($orig_body, $img_start), ']') : false);
  87. $img_end = ($img_start !== false ? strpos(substr($orig_body, $img_start), '[/img]') : false);
  88. while(($img_st_close !== false) && ($img_end !== false)) {
  89. $img_st_close++; // make it point to AFTER the closing bracket
  90. $img_end += $img_start;
  91. if(! strcmp(substr($orig_body, $img_start + $img_st_close, 5), 'data:')) {
  92. // This is an embedded image
  93. $saved_image[$cnt] = substr($orig_body, $img_start + $img_st_close, $img_end - ($img_start + $img_st_close));
  94. $new_body = $new_body . substr($orig_body, 0, $img_start) . '[!#saved_image' . $cnt . '#!]';
  95. $cnt++;
  96. }
  97. else
  98. $new_body = $new_body . substr($orig_body, 0, $img_end + strlen('[/img]'));
  99. $orig_body = substr($orig_body, $img_end + strlen('[/img]'));
  100. if($orig_body === false) // in case the body ends on a closing image tag
  101. $orig_body = '';
  102. $img_start = strpos($orig_body, '[img');
  103. $img_st_close = ($img_start !== false ? strpos(substr($orig_body, $img_start), ']') : false);
  104. $img_end = ($img_start !== false ? strpos(substr($orig_body, $img_start), '[/img]') : false);
  105. }
  106. $new_body = $new_body . $orig_body;
  107. return array('body' => $new_body, 'images' => $saved_image);
  108. }}
  109. if(! function_exists('item_redir_and_replace_images')) {
  110. function item_redir_and_replace_images($body, $images, $cid) {
  111. $origbody = $body;
  112. $newbody = '';
  113. for($i = 0; $i < count($images); $i++) {
  114. $search = '/\[url\=(.*?)\]\[!#saved_image' . $i . '#!\]\[\/url\]' . '/is';
  115. $replace = '[url=' . z_path() . '/redir/' . $cid
  116. . '?f=1&url=' . '$1' . '][!#saved_image' . $i . '#!][/url]' ;
  117. $img_end = strpos($origbody, '[!#saved_image' . $i . '#!][/url]') + strlen('[!#saved_image' . $i . '#!][/url]');
  118. $process_part = substr($origbody, 0, $img_end);
  119. $origbody = substr($origbody, $img_end);
  120. $process_part = preg_replace($search, $replace, $process_part);
  121. $newbody = $newbody . $process_part;
  122. }
  123. $newbody = $newbody . $origbody;
  124. $cnt = 0;
  125. foreach($images as $image) {
  126. // We're depending on the property of 'foreach' (specified on the PHP website) that
  127. // it loops over the array starting from the first element and going sequentially
  128. // to the last element
  129. $newbody = str_replace('[!#saved_image' . $cnt . '#!]', '[img]' . $image . '[/img]', $newbody);
  130. $cnt++;
  131. }
  132. return $newbody;
  133. }}
  134. function message_content(&$a) {
  135. $o = '';
  136. nav_set_selected('messages');
  137. if(! local_user()) {
  138. notice( t('Permission denied.') . EOL);
  139. return;
  140. }
  141. $myprofile = $a->get_baseurl(true) . '/profile/' . $a->user['nickname'];
  142. $tpl = get_markup_template('mail_head.tpl');
  143. $header = replace_macros($tpl, array(
  144. '$messages' => t('Messages'),
  145. '$tab_content' => $tab_content
  146. ));
  147. if(($a->argc == 3) && ($a->argv[1] === 'drop' || $a->argv[1] === 'dropconv')) {
  148. if(! intval($a->argv[2]))
  149. return;
  150. // Check if we should do HTML-based delete confirmation
  151. if($_REQUEST['confirm']) {
  152. // <form> can't take arguments in its "action" parameter
  153. // so add any arguments as hidden inputs
  154. $query = explode_querystring($a->query_string);
  155. $inputs = array();
  156. foreach($query['args'] as $arg) {
  157. if(strpos($arg, 'confirm=') === false) {
  158. $arg_parts = explode('=', $arg);
  159. $inputs[] = array('name' => $arg_parts[0], 'value' => $arg_parts[1]);
  160. }
  161. }
  162. //$a->page['aside'] = '';
  163. return replace_macros(get_markup_template('confirm.tpl'), array(
  164. '$method' => 'get',
  165. '$message' => t('Do you really want to delete this message?'),
  166. '$extra_inputs' => $inputs,
  167. '$confirm' => t('Yes'),
  168. '$confirm_url' => $query['base'],
  169. '$confirm_name' => 'confirmed',
  170. '$cancel' => t('Cancel'),
  171. ));
  172. }
  173. // Now check how the user responded to the confirmation query
  174. if($_REQUEST['canceled']) {
  175. goaway($a->get_baseurl(true) . '/' . $_SESSION['return_url']);
  176. }
  177. $cmd = $a->argv[1];
  178. if($cmd === 'drop') {
  179. $r = q("DELETE FROM `mail` WHERE `id` = %d AND `uid` = %d LIMIT 1",
  180. intval($a->argv[2]),
  181. intval(local_user())
  182. );
  183. if($r) {
  184. info( t('Message deleted.') . EOL );
  185. }
  186. //goaway($a->get_baseurl(true) . '/message' );
  187. goaway($a->get_baseurl(true) . '/' . $_SESSION['return_url']);
  188. }
  189. else {
  190. $r = q("SELECT `parent-uri`,`convid` FROM `mail` WHERE `id` = %d AND `uid` = %d LIMIT 1",
  191. intval($a->argv[2]),
  192. intval(local_user())
  193. );
  194. if(count($r)) {
  195. $parent = $r[0]['parent-uri'];
  196. $convid = $r[0]['convid'];
  197. $r = q("DELETE FROM `mail` WHERE `parent-uri` = '%s' AND `uid` = %d ",
  198. dbesc($parent),
  199. intval(local_user())
  200. );
  201. // remove diaspora conversation pointer
  202. // Actually if we do this, we can never receive another reply to that conversation,
  203. // as we will never again have the info we need to re-create it.
  204. // We'll just have to orphan it.
  205. //if($convid) {
  206. // q("delete from conv where id = %d limit 1",
  207. // intval($convid)
  208. // );
  209. //}
  210. if($r)
  211. info( t('Conversation removed.') . EOL );
  212. }
  213. //goaway($a->get_baseurl(true) . '/message' );
  214. goaway($a->get_baseurl(true) . '/' . $_SESSION['return_url']);
  215. }
  216. }
  217. if(($a->argc > 1) && ($a->argv[1] === 'new')) {
  218. $o .= $header;
  219. /* $plaintext = false;
  220. if(intval(get_pconfig(local_user(),'system','plaintext')))
  221. $plaintext = true;*/
  222. $plaintext = true;
  223. if( local_user() && feature_enabled(local_user(),'richtext') )
  224. $plaintext = false;
  225. $tpl = get_markup_template('msg-header.tpl');
  226. $a->page['htmlhead'] .= replace_macros($tpl, array(
  227. '$baseurl' => $a->get_baseurl(true),
  228. '$editselect' => (($plaintext) ? 'none' : '/(profile-jot-text|prvmail-text)/'),
  229. '$nickname' => $a->user['nickname'],
  230. '$linkurl' => t('Please enter a link URL:')
  231. ));
  232. $tpl = get_markup_template('msg-end.tpl');
  233. $a->page['end'] .= replace_macros($tpl, array(
  234. '$baseurl' => $a->get_baseurl(true),
  235. '$editselect' => (($plaintext) ? 'none' : '/(profile-jot-text|prvmail-text)/'),
  236. '$nickname' => $a->user['nickname'],
  237. '$linkurl' => t('Please enter a link URL:')
  238. ));
  239. $preselect = (isset($a->argv[2])?array($a->argv[2]):false);
  240. $prename = $preurl = $preid = '';
  241. if($preselect) {
  242. $r = q("select name, url, id from contact where uid = %d and id = %d limit 1",
  243. intval(local_user()),
  244. intval($a->argv[2])
  245. );
  246. if(count($r)) {
  247. $prename = $r[0]['name'];
  248. $preurl = $r[0]['url'];
  249. $preid = $r[0]['id'];
  250. }
  251. }
  252. $prefill = (($preselect) ? $prename : '');
  253. // the ugly select box
  254. $select = contact_select('messageto','message-to-select', $preselect, 4, true, false, false, 10);
  255. $tpl = get_markup_template('prv_message.tpl');
  256. $o .= replace_macros($tpl,array(
  257. '$header' => t('Send Private Message'),
  258. '$to' => t('To:'),
  259. '$showinputs' => 'true',
  260. '$prefill' => $prefill,
  261. '$autocomp' => $autocomp,
  262. '$preid' => $preid,
  263. '$subject' => t('Subject:'),
  264. '$subjtxt' => ((x($_REQUEST,'subject')) ? strip_tags($_REQUEST['subject']) : ''),
  265. '$text' => ((x($_REQUEST,'body')) ? escape_tags(htmlspecialchars($_REQUEST['body'])) : ''),
  266. '$readonly' => '',
  267. '$yourmessage' => t('Your message:'),
  268. '$select' => $select,
  269. '$parent' => '',
  270. '$upload' => t('Upload photo'),
  271. '$insert' => t('Insert web link'),
  272. '$wait' => t('Please wait'),
  273. '$submit' => t('Submit')
  274. ));
  275. return $o;
  276. }
  277. $_SESSION['return_url'] = $a->query_string;
  278. if($a->argc == 1) {
  279. // List messages
  280. $o .= $header;
  281. $r = q("SELECT count(*) AS `total` FROM `mail`
  282. WHERE `mail`.`uid` = %d GROUP BY `parent-uri` ORDER BY `created` DESC",
  283. intval(local_user()),
  284. dbesc($myprofile)
  285. );
  286. if(count($r)) $a->set_pager_total($r[0]['total']);
  287. $r = get_messages(local_user(), $a->pager['start'], $a->pager['itemspage']);
  288. if(! count($r)) {
  289. info( t('No messages.') . EOL);
  290. return $o;
  291. }
  292. $o .= render_messages($r, 'mail_list.tpl');
  293. $o .= paginate($a);
  294. return $o;
  295. }
  296. if(($a->argc > 1) && (intval($a->argv[1]))) {
  297. $o .= $header;
  298. $plaintext = true;
  299. if( local_user() && feature_enabled(local_user(),'richtext') )
  300. $plaintext = false;
  301. $r = q("SELECT `mail`.*, `contact`.`name`, `contact`.`url`, `contact`.`thumb`
  302. FROM `mail` LEFT JOIN `contact` ON `mail`.`contact-id` = `contact`.`id`
  303. WHERE `mail`.`uid` = %d AND `mail`.`id` = %d LIMIT 1",
  304. intval(local_user()),
  305. intval($a->argv[1])
  306. );
  307. if(count($r)) {
  308. $contact_id = $r[0]['contact-id'];
  309. $convid = $r[0]['convid'];
  310. $sql_extra = sprintf(" and `mail`.`parent-uri` = '%s' ", dbesc($r[0]['parent-uri']));
  311. if($convid)
  312. $sql_extra = sprintf(" and ( `mail`.`parent-uri` = '%s' OR `mail`.`convid` = '%d' ) ",
  313. dbesc($r[0]['parent-uri']),
  314. intval($convid)
  315. );
  316. $messages = q("SELECT `mail`.*, `contact`.`name`, `contact`.`url`, `contact`.`thumb`
  317. FROM `mail` LEFT JOIN `contact` ON `mail`.`contact-id` = `contact`.`id`
  318. WHERE `mail`.`uid` = %d $sql_extra ORDER BY `mail`.`created` ASC",
  319. intval(local_user())
  320. );
  321. }
  322. if(! count($messages)) {
  323. notice( t('Message not available.') . EOL );
  324. return $o;
  325. }
  326. $r = q("UPDATE `mail` SET `seen` = 1 WHERE `parent-uri` = '%s' AND `uid` = %d",
  327. dbesc($r[0]['parent-uri']),
  328. intval(local_user())
  329. );
  330. require_once("include/bbcode.php");
  331. $tpl = get_markup_template('msg-header.tpl');
  332. $a->page['htmlhead'] .= replace_macros($tpl, array(
  333. '$baseurl' => $a->get_baseurl(true),
  334. '$editselect' => (($plaintext) ? 'none' : '/(profile-jot-text|prvmail-text)/'),
  335. '$nickname' => $a->user['nickname'],
  336. '$linkurl' => t('Please enter a link URL:')
  337. ));
  338. $tpl = get_markup_template('msg-end.tpl');
  339. $a->page['end'] .= replace_macros($tpl, array(
  340. '$baseurl' => $a->get_baseurl(true),
  341. '$editselect' => (($plaintext) ? 'none' : '/(profile-jot-text|prvmail-text)/'),
  342. '$nickname' => $a->user['nickname'],
  343. '$linkurl' => t('Please enter a link URL:')
  344. ));
  345. $mails = array();
  346. $seen = 0;
  347. $unknown = false;
  348. foreach($messages as $message) {
  349. if($message['unknown'])
  350. $unknown = true;
  351. if($message['from-url'] == $myprofile) {
  352. $from_url = $myprofile;
  353. $sparkle = '';
  354. }
  355. else {
  356. $from_url = $a->get_baseurl(true) . '/redir/' . $message['contact-id'];
  357. $sparkle = ' sparkle';
  358. }
  359. $extracted = item_extract_images($message['body']);
  360. if($extracted['images'])
  361. $message['body'] = item_redir_and_replace_images($extracted['body'], $extracted['images'], $message['contact-id']);
  362. if($a->theme['template_engine'] === 'internal') {
  363. $from_name_e = template_escape($message['from-name']);
  364. $subject_e = template_escape($message['title']);
  365. $body_e = template_escape(smilies(bbcode($message['body'])));
  366. $to_name_e = template_escape($message['name']);
  367. }
  368. else {
  369. $from_name_e = $message['from-name'];
  370. $subject_e = $message['title'];
  371. $body_e = smilies(bbcode($message['body']));
  372. $to_name_e = $message['name'];
  373. }
  374. $mails[] = array(
  375. 'id' => $message['id'],
  376. 'from_name' => $from_name_e,
  377. 'from_url' => $from_url,
  378. 'sparkle' => $sparkle,
  379. 'from_photo' => $message['from-photo'],
  380. 'subject' => $subject_e,
  381. 'body' => $body_e,
  382. 'delete' => t('Delete message'),
  383. 'to_name' => $to_name_e,
  384. 'date' => datetime_convert('UTC',date_default_timezone_get(),$message['created'],'D, d M Y - g:i A'),
  385. 'ago' => relative_date($message['created']),
  386. );
  387. $seen = $message['seen'];
  388. }
  389. $select = $message['name'] . '<input type="hidden" name="messageto" value="' . $contact_id . '" />';
  390. $parent = '<input type="hidden" name="replyto" value="' . $message['parent-uri'] . '" />';
  391. $tpl = get_markup_template('mail_display.tpl');
  392. if($a->theme['template_engine'] === 'internal') {
  393. $subjtxt_e = template_escape($message['title']);
  394. }
  395. else {
  396. $subjtxt_e = $message['title'];
  397. }
  398. $o = replace_macros($tpl, array(
  399. '$thread_id' => $a->argv[1],
  400. '$thread_subject' => $message['title'],
  401. '$thread_seen' => $seen,
  402. '$delete' => t('Delete conversation'),
  403. '$canreply' => (($unknown) ? false : '1'),
  404. '$unknown_text' => t("No secure communications available. You <strong>may</strong> be able to respond from the sender's profile page."),
  405. '$mails' => $mails,
  406. // reply
  407. '$header' => t('Send Reply'),
  408. '$to' => t('To:'),
  409. '$showinputs' => '',
  410. '$subject' => t('Subject:'),
  411. '$subjtxt' => $subjtxt_e,
  412. '$readonly' => ' readonly="readonly" style="background: #BBBBBB;" ',
  413. '$yourmessage' => t('Your message:'),
  414. '$text' => '',
  415. '$select' => $select,
  416. '$parent' => $parent,
  417. '$upload' => t('Upload photo'),
  418. '$insert' => t('Insert web link'),
  419. '$submit' => t('Submit'),
  420. '$wait' => t('Please wait')
  421. ));
  422. return $o;
  423. }
  424. }
  425. function get_messages($user, $lstart, $lend) {
  426. return q("SELECT max(`mail`.`created`) AS `mailcreated`, min(`mail`.`seen`) AS `mailseen`,
  427. `mail`.* , `contact`.`name`, `contact`.`url`, `contact`.`thumb` , `contact`.`network`,
  428. count( * ) as count
  429. FROM `mail` LEFT JOIN `contact` ON `mail`.`contact-id` = `contact`.`id`
  430. WHERE `mail`.`uid` = %d GROUP BY `parent-uri` ORDER BY `mailcreated` DESC LIMIT %d , %d ",
  431. intval($user), intval($lstart), intval($lend)
  432. );
  433. }
  434. function render_messages($msg, $t) {
  435. $a = get_app();
  436. $tpl = get_markup_template($t);
  437. $rslt = '';
  438. $myprofile = $a->get_baseurl(true) . '/profile/' . $a->user['nickname'];
  439. foreach($msg as $rr) {
  440. if($rr['unknown']) {
  441. $participants = sprintf( t("Unknown sender - %s"),$rr['from-name']);
  442. }
  443. elseif (link_compare($rr['from-url'], $myprofile)){
  444. $participants = sprintf( t("You and %s"), $rr['name']);
  445. }
  446. else {
  447. $participants = sprintf( t("%s and You"), $rr['from-name']);
  448. }
  449. if($a->theme['template_engine'] === 'internal') {
  450. $subject_e = template_escape((($rr['mailseen']) ? $rr['title'] : '<strong>' . $rr['title'] . '</strong>'));
  451. $body_e = template_escape($rr['body']);
  452. $to_name_e = template_escape($rr['name']);
  453. }
  454. else {
  455. $subject_e = (($rr['mailseen']) ? $rr['title'] : '<strong>' . $rr['title'] . '</strong>');
  456. $body_e = $rr['body'];
  457. $to_name_e = $rr['name'];
  458. }
  459. $rslt .= replace_macros($tpl, array(
  460. '$id' => $rr['id'],
  461. '$from_name' => $participants,
  462. '$from_url' => (($rr['network'] === NETWORK_DFRN) ? $a->get_baseurl(true) . '/redir/' . $rr['contact-id'] : $rr['url']),
  463. '$sparkle' => ' sparkle',
  464. '$from_photo' => (($rr['thumb']) ? $rr['thumb'] : $rr['from-photo']),
  465. '$subject' => $subject_e,
  466. '$delete' => t('Delete conversation'),
  467. '$body' => $body_e,
  468. '$to_name' => $to_name_e,
  469. '$date' => datetime_convert('UTC',date_default_timezone_get(),$rr['mailcreated'], t('D, d M Y - g:i A')),
  470. '$ago' => relative_date($rr['mailcreated']),
  471. '$seen' => $rr['mailseen'],
  472. '$count' => sprintf( tt('%d message', '%d messages', $rr['count']), $rr['count']),
  473. ));
  474. }
  475. return $rslt;
  476. }