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.

312 lines
8.9 KiB

10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
  1. <?php
  2. require_once('include/html2plain.php');
  3. require_once('include/msgclean.php');
  4. require_once('include/quoteconvert.php');
  5. function email_connect($mailbox,$username,$password) {
  6. if(! function_exists('imap_open'))
  7. return false;
  8. $mbox = @imap_open($mailbox,$username,$password);
  9. return $mbox;
  10. }
  11. function email_poll($mbox,$email_addr) {
  12. if(! ($mbox && $email_addr))
  13. return array();
  14. $search1 = @imap_search($mbox,'FROM "' . $email_addr . '"', SE_UID);
  15. if(! $search1)
  16. $search1 = array();
  17. $search2 = @imap_search($mbox,'TO "' . $email_addr . '"', SE_UID);
  18. if(! $search2)
  19. $search2 = array();
  20. $search3 = @imap_search($mbox,'CC "' . $email_addr . '"', SE_UID);
  21. if(! $search3)
  22. $search3 = array();
  23. $search4 = @imap_search($mbox,'BCC "' . $email_addr . '"', SE_UID);
  24. if(! $search4)
  25. $search4 = array();
  26. $res = array_unique(array_merge($search1,$search2,$search3,$search4));
  27. return $res;
  28. }
  29. function construct_mailbox_name($mailacct) {
  30. $ret = '{' . $mailacct['server'] . ((intval($mailacct['port'])) ? ':' . $mailacct['port'] : '');
  31. $ret .= (($mailacct['ssltype']) ? '/' . $mailacct['ssltype'] . '/novalidate-cert' : '');
  32. $ret .= '}' . $mailacct['mailbox'];
  33. return $ret;
  34. }
  35. function email_msg_meta($mbox,$uid) {
  36. $ret = (($mbox && $uid) ? @imap_fetch_overview($mbox,$uid,FT_UID) : array(array())); // POSSIBLE CLEANUP --> array(array()) is probably redundant now
  37. return ((count($ret)) ? $ret : array());
  38. }
  39. function email_msg_headers($mbox,$uid) {
  40. $raw_header = (($mbox && $uid) ? @imap_fetchheader($mbox,$uid,FT_UID) : '');
  41. $raw_header = str_replace("\r",'',$raw_header);
  42. $ret = array();
  43. $h = explode("\n",$raw_header);
  44. if(count($h))
  45. foreach($h as $line ) {
  46. if (preg_match("/^[a-zA-Z]/", $line)) {
  47. $key = substr($line,0,strpos($line,':'));
  48. $value = substr($line,strpos($line,':')+1);
  49. $last_entry = strtolower($key);
  50. $ret[$last_entry] = trim($value);
  51. }
  52. else {
  53. $ret[$last_entry] .= ' ' . trim($line);
  54. }
  55. }
  56. return $ret;
  57. }
  58. function email_get_msg($mbox,$uid, $reply) {
  59. $ret = array();
  60. $struc = (($mbox && $uid) ? @imap_fetchstructure($mbox,$uid,FT_UID) : null);
  61. if(! $struc)
  62. return $ret;
  63. if(! $struc->parts) {
  64. $ret['body'] = email_get_part($mbox,$uid,$struc,0, 'html');
  65. $html = $ret['body'];
  66. if (trim($ret['body']) == '')
  67. $ret['body'] = email_get_part($mbox,$uid,$struc,0, 'plain');
  68. else
  69. $ret['body'] = html2bbcode($ret['body']);
  70. }
  71. else {
  72. $text = '';
  73. $html = '';
  74. foreach($struc->parts as $ptop => $p) {
  75. $x = email_get_part($mbox,$uid,$p,$ptop + 1, 'plain');
  76. if ($x) {
  77. $text .= $x;
  78. }
  79. $x = email_get_part($mbox,$uid,$p,$ptop + 1, 'html');
  80. if ($x) {
  81. $html .= $x;
  82. }
  83. }
  84. if (trim($html) != '') {
  85. $ret['body'] = html2bbcode($html);
  86. } else {
  87. $ret['body'] = $text;
  88. }
  89. }
  90. $ret['body'] = removegpg($ret['body']);
  91. $msg = removesig($ret['body']);
  92. $ret['body'] = $msg['body'];
  93. $ret['body'] = convertquote($ret['body'], $reply);
  94. if (trim($html) != '') {
  95. $ret['body'] = removelinebreak($ret['body']);
  96. }
  97. $ret['body'] = unifyattributionline($ret['body']);
  98. return $ret;
  99. }
  100. // At the moment - only return plain/text.
  101. // Later we'll repackage inline images as data url's and make the HTML safe
  102. function email_get_part($mbox,$uid,$p,$partno, $subtype) {
  103. // $partno = '1', '2', '2.1', '2.1.3', etc for multipart, 0 if simple
  104. global $htmlmsg,$plainmsg,$charset,$attachments;
  105. //echo $partno."\n";
  106. // DECODE DATA
  107. $data = ($partno)
  108. ? @imap_fetchbody($mbox,$uid,$partno, FT_UID|FT_PEEK)
  109. : @imap_body($mbox,$uid,FT_UID|FT_PEEK);
  110. // Any part may be encoded, even plain text messages, so check everything.
  111. if ($p->encoding==4)
  112. $data = quoted_printable_decode($data);
  113. elseif ($p->encoding==3)
  114. $data = base64_decode($data);
  115. // PARAMETERS
  116. // get all parameters, like charset, filenames of attachments, etc.
  117. $params = array();
  118. if ($p->parameters)
  119. foreach ($p->parameters as $x)
  120. $params[strtolower($x->attribute)] = $x->value;
  121. if (isset($p->dparameters) and $p->dparameters)
  122. foreach ($p->dparameters as $x)
  123. $params[strtolower($x->attribute)] = $x->value;
  124. // ATTACHMENT
  125. // Any part with a filename is an attachment,
  126. // so an attached text file (type 0) is not mistaken as the message.
  127. if ((isset($params['filename']) and $params['filename']) || (isset($params['name']) and $params['name'])) {
  128. // filename may be given as 'Filename' or 'Name' or both
  129. $filename = ($params['filename'])? $params['filename'] : $params['name'];
  130. // filename may be encoded, so see imap_mime_header_decode()
  131. $attachments[$filename] = $data; // this is a problem if two files have same name
  132. }
  133. // TEXT
  134. if ($p->type == 0 && $data) {
  135. // Messages may be split in different parts because of inline attachments,
  136. // so append parts together with blank row.
  137. if (strtolower($p->subtype)==$subtype) {
  138. $data = iconv($params['charset'], 'UTF-8//IGNORE', $data);
  139. return (trim($data) ."\n\n");
  140. } else
  141. $data = '';
  142. // $htmlmsg .= $data ."<br><br>";
  143. $charset = $params['charset']; // assume all parts are same charset
  144. }
  145. // EMBEDDED MESSAGE
  146. // Many bounce notifications embed the original message as type 2,
  147. // but AOL uses type 1 (multipart), which is not handled here.
  148. // There are no PHP functions to parse embedded messages,
  149. // so this just appends the raw source to the main message.
  150. // elseif ($p->type==2 && $data) {
  151. // $plainmsg .= $data."\n\n";
  152. // }
  153. // SUBPART RECURSION
  154. if (isset($p->parts) and $p->parts) {
  155. $x = "";
  156. foreach ($p->parts as $partno0=>$p2) {
  157. $x .= email_get_part($mbox,$uid,$p2,$partno . '.' . ($partno0+1), $subtype); // 1.2, 1.2.1, etc.
  158. //if ($x) {
  159. // return $x;
  160. //}
  161. }
  162. return $x;
  163. }
  164. }
  165. function email_header_encode($in_str, $charset) {
  166. $out_str = $in_str;
  167. $need_to_convert = false;
  168. for($x = 0; $x < strlen($in_str); $x ++) {
  169. if((ord($in_str[$x]) == 0) || ((ord($in_str[$x]) > 128))) {
  170. $need_to_convert = true;
  171. }
  172. }
  173. if(! $need_to_convert)
  174. return $in_str;
  175. if ($out_str && $charset) {
  176. // define start delimimter, end delimiter and spacer
  177. $end = "?=";
  178. $start = "=?" . $charset . "?B?";
  179. $spacer = $end . "\r\n " . $start;
  180. // determine length of encoded text within chunks
  181. // and ensure length is even
  182. $length = 75 - strlen($start) - strlen($end);
  183. /*
  184. [EDIT BY danbrown AT php DOT net: The following
  185. is a bugfix provided by (gardan AT gmx DOT de)
  186. on 31-MAR-2005 with the following note:
  187. "This means: $length should not be even,
  188. but divisible by 4. The reason is that in
  189. base64-encoding 3 8-bit-chars are represented
  190. by 4 6-bit-chars. These 4 chars must not be
  191. split between two encoded words, according
  192. to RFC-2047.
  193. */
  194. $length = $length - ($length % 4);
  195. // encode the string and split it into chunks
  196. // with spacers after each chunk
  197. $out_str = base64_encode($out_str);
  198. $out_str = chunk_split($out_str, $length, $spacer);
  199. // remove trailing spacer and
  200. // add start and end delimiters
  201. $spacer = preg_quote($spacer,'/');
  202. $out_str = preg_replace("/" . $spacer . "$/", "", $out_str);
  203. $out_str = $start . $out_str . $end;
  204. }
  205. return $out_str;
  206. }
  207. /**
  208. * email_send is used by NETWORK_EMAIL and NETWORK_EMAIL2 code
  209. * (not to notify the user, but to send items to email contacts)
  210. *
  211. * @todo This could be changed to use the Emailer class
  212. */
  213. function email_send($addr, $subject, $headers, $item) {
  214. //$headers .= 'MIME-Version: 1.0' . "\n";
  215. //$headers .= 'Content-Type: text/html; charset=UTF-8' . "\n";
  216. //$headers .= 'Content-Type: text/plain; charset=UTF-8' . "\n";
  217. //$headers .= 'Content-Transfer-Encoding: 8bit' . "\n\n";
  218. $part = uniqid("", true);
  219. $html = prepare_body($item);
  220. $headers .= "Mime-Version: 1.0\n";
  221. $headers .= 'Content-Type: multipart/alternative; boundary="=_'.$part.'"'."\n\n";
  222. $body = "\n--=_".$part."\n";
  223. $body .= "Content-Transfer-Encoding: 8bit\n";
  224. $body .= "Content-Type: text/plain; charset=utf-8; format=flowed\n\n";
  225. $body .= html2plain($html)."\n";
  226. $body .= "--=_".$part."\n";
  227. $body .= "Content-Transfer-Encoding: 8bit\n";
  228. $body .= "Content-Type: text/html; charset=utf-8\n\n";
  229. $body .= '<html><head></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; ">'.$html."</body></html>\n";
  230. $body .= "--=_".$part."--";
  231. //$message = '<html><body>' . $html . '</body></html>';
  232. //$message = html2plain($html);
  233. logger('notifier: email delivery to ' . $addr);
  234. mail($addr, $subject, $body, $headers);
  235. }
  236. function iri2msgid($iri) {
  237. if (!strpos($iri, "@"))
  238. $msgid = preg_replace("/urn:(\S+):(\S+)\.(\S+):(\d+):(\S+)/i", "urn!$1!$4!$5@$2.$3", $iri);
  239. else
  240. $msgid = $iri;
  241. return($msgid);
  242. }
  243. function msgid2iri($msgid) {
  244. if (strpos($msgid, "@"))
  245. $iri = preg_replace("/urn!(\S+)!(\d+)!(\S+)@(\S+)\.(\S+)/i", "urn:$1:$4.$5:$2:$3", $msgid);
  246. else
  247. $iri = $msgid;
  248. return($iri);
  249. }