PageRenderTime 27ms CodeModel.GetById 22ms RepoModel.GetById 0ms app.codeStats 0ms

/libs/Albireo/Mail/MailReceiver.php

https://code.google.com/
PHP | 434 lines | 254 code | 29 blank | 151 comment | 73 complexity | 663d70221ac850cb0104489e86c03b0d MD5 | raw file
Possible License(s): Apache-2.0, GPL-2.0
  1. <?php
  2. /**
  3. * Celebrio Library
  4. *
  5. * @copyright Copyright (c) 2011 Celebrio Software
  6. * @package GoogleAPI
  7. */
  8. namespace Celebrio\Mail;
  9. use Nette\Object;
  10. use ApplicationsModule\MailModule\Attachment;
  11. use Nette\Image;
  12. class MailReceiver extends Object {
  13. private $server='';
  14. private $username='';
  15. private $password='';
  16. private $imap_stream='';
  17. private $email='';
  18. public function __construct($username,$password,$EmailAddress,$mailserver='localhost',$servertype='pop',$port='110',$ssl = false)
  19. {
  20. if($servertype=='imap')
  21. {
  22. if($port=='') $port='143';
  23. $strConnect='{'.$mailserver.':'.$port.($ssl ? "/ssl" : "").'}';
  24. } else {
  25. $strConnect='{'.$mailserver.':'.$port. '/pop3'.($ssl ? "/ssl" : "").'}';
  26. }
  27. $this->server = $strConnect;
  28. $this->username = $username;
  29. $this->password = $password;
  30. $this->email = $EmailAddress;
  31. }
  32. /**
  33. * connects to the server
  34. * @return boolean false if connection fails, true if it works
  35. */
  36. public function connect($folder="INBOX")
  37. {
  38. $this->imap_stream=@imap_open($this->server.$folder,$this->username,$this->password,OP_SILENT);
  39. // next two lines silence imap errors
  40. imap_errors();
  41. imap_alerts();
  42. if($this->imap_stream) return true;
  43. else return false;
  44. }
  45. /**
  46. * gets mail folders for sent, drafts, trash and spam
  47. * usually supported only by IMAP
  48. * @return array("Sent"=>string,"Drafts"=>string,"Trash"=>string,"Spam"=>string)
  49. */
  50. public function getMailFolders() {
  51. $folders = array("Sent"=>"","Drafts"=>"","Trash"=>"","Spam"=>"");
  52. $list = \imap_list($this->imap_stream, $this->server, "*");
  53. if(\is_array($list)){
  54. $offset = \strlen($this->server)-1;
  55. foreach($list as $row){
  56. if(stripos($row,"Sent",$offset))$folders["Sent"] = \substr($row,\strpos($row,"}",$offset-1)+1,\strlen($row));
  57. elseif(stripos($row,"Draft",$offset))$folders["Drafts"] = \substr($row,\strpos($row,"}",$offset-1)+1,\strlen($row));
  58. elseif(stripos($row,"Trash",$offset)||stripos($row,"Deleted",$offset))$folders["Trash"] = \substr($row,\strpos($row,"}",$offset-1)+1,\strlen($row));
  59. elseif(stripos($row,"Spam",$offset)||stripos($row,"Junk",$offset))$folders["Spam"] = \substr($row,\strpos($row,"}",$offset-1)+1,\strlen($row));
  60. }
  61. }
  62. return $folders;
  63. }
  64. /**
  65. * Receive a string with a mail header and returns it decoded to a specified charset.
  66. * If the charset specified into a piece of text from header isn't supported by "mb", the "fallbackCharset" will be used to try to decode it.
  67. * @param <type> $mimeStr
  68. * @param <type> $inputCharset
  69. * @param <type> $targetCharset
  70. * @param <type> $fallbackCharset
  71. * @return <type>
  72. */
  73. public function decodeMimeString($mimeStr, $inputCharset='utf-8', $targetCharset='utf-8', $fallbackCharset='iso-8859-2') {
  74. $encodings=mb_list_encodings();
  75. for ($n=sizeOf($encodings); $n--; ) { $encodings[$n]=strtolower($encodings[$n]); }
  76. $inputCharset=strtolower($inputCharset);
  77. $targetCharset=strtolower($targetCharset);
  78. $fallbackCharset=strtolower($fallbackCharset);
  79. $decodedStr='';
  80. $mimeStrs=imap_mime_header_decode($mimeStr);
  81. for ($n=sizeOf($mimeStrs), $i=0; $i<$n; $i++) {
  82. $mimeStr=$mimeStrs[$i];
  83. $mimeStr->charset=strtolower($mimeStr->charset);
  84. if (($mimeStr == 'default' && $inputCharset == $targetCharset) //WTF?? nema to byt skor $mimeStr->charset == 'default'
  85. || $mimeStr->charset == $targetCharset) {
  86. $decodedStr.=$mimeStr->text;
  87. } else {
  88. $decodedStr.=mb_convert_encoding(
  89. $mimeStr->text, $targetCharset,
  90. (in_array($mimeStr->charset, $encodings) ?
  91. $mimeStr->charset : $fallbackCharset));
  92. }
  93. }
  94. return $decodedStr;
  95. }
  96. /**
  97. * gets an e-mail header
  98. *
  99. * toaddress - full to: line, up to 1024 characters
  100. * to - an array of objects from the To: line, with the following properties: personal, adl, mailbox, and host
  101. * fromaddress - full from: line, up to 1024 characters
  102. * from - an array of objects from the From: line, with the following properties: personal, adl, mailbox, and host
  103. * ccaddress - full cc: line, up to 1024 characters
  104. * cc - an array of objects from the Cc: line, with the following properties: personal, adl, mailbox, and host
  105. * bccaddress - full bcc: line, up to 1024 characters
  106. * bcc - an array of objects from the Bcc: line, with the following properties: personal, adl, mailbox, and host
  107. * reply_toaddress - full Reply-To: line, up to 1024 characters
  108. * reply_to - an array of objects from the Reply-To: line, with the following properties: personal, adl, mailbox, and host
  109. * senderaddress - full sender: line, up to 1024 characters
  110. * sender - an array of objects from the Sender: line, with the following properties: personal, adl, mailbox, and host
  111. * return_pathaddress - full Return-Path: line, up to 1024 characters
  112. * return_path - an array of objects from the Return-Path: line, with the following properties: personal, adl, mailbox, and host
  113. * remail -
  114. * date - The message date as found in its headers
  115. * Date - Same as date
  116. * subject - The message subject
  117. * Subject - Same a subject
  118. * in_reply_to -
  119. * message_id -
  120. * newsgroups -
  121. * followup_to -
  122. * references -
  123. * Recent - R if recent and seen, N if recent and not seen, ' ' if not recent.
  124. * Unseen - U if not seen AND not recent, ' ' if seen OR not seen and recent
  125. * Flagged - F if flagged, ' ' if not flagged
  126. * Answered - A if answered, ' ' if unanswered
  127. * Deleted - D if deleted, ' ' if not deleted
  128. * Draft - X if draft, ' ' if not draft
  129. * Msgno - The message number
  130. * MailDate -
  131. * Size - The message size
  132. * udate - mail message date in Unix time
  133. * fetchfrom - from line formatted to fit fromlength characters
  134. * fetchsubject - subject line formatted to fit subjectlength characters
  135. *
  136. * @param int $mail_number
  137. * @return header object
  138. */
  139. public function getHeader($mail_number) {
  140. if(!$this->imap_stream) return false;
  141. return imap_headerinfo($this->imap_stream, $mail_number);
  142. }
  143. public function getHeaders($start, $end) {
  144. if(!$this->imap_stream) return false;
  145. $headers = array();
  146. $sequence = $start.":".$end;
  147. $headers = imap_fetch_overview($this->imap_stream, $sequence);
  148. return $headers;
  149. }
  150. function get_mime_type(&$structure) //Get Mime type Internal Private Use
  151. {
  152. $primary_mime_type = array("TEXT", "MULTIPART", "MESSAGE", "APPLICATION", "AUDIO", "IMAGE", "VIDEO", "OTHER");
  153. if($structure->subtype) {
  154. return $primary_mime_type[(int) $structure->type] . '/' . $structure->subtype;
  155. }
  156. return "TEXT/PLAIN";
  157. }
  158. /**
  159. * Get Part Of Message
  160. * @param <type> $stream
  161. * @param <type> $msg_number
  162. * @param <type> $mime_type
  163. * @param <type> $structure
  164. * @param string $part_number
  165. * @return <type>
  166. */
  167. private function get_part($stream, $msg_number, $mime_type, $structure = false, $part_number = false)
  168. {
  169. if(!$structure) {
  170. $structure = imap_fetchstructure($stream, $msg_number);
  171. }
  172. if($structure) {
  173. if($mime_type == $this->get_mime_type($structure))
  174. {
  175. if(!$part_number)
  176. {
  177. $part_number = "1";
  178. }
  179. $text = imap_fetchbody($stream, $msg_number, $part_number);
  180. if($structure->encoding == 3)
  181. {
  182. return imap_base64($text);
  183. }
  184. else if($structure->encoding == 4)
  185. {
  186. return imap_qprint($text);
  187. }
  188. else
  189. {
  190. return $text;
  191. }
  192. }
  193. if($structure->type == 1) /* multipart */
  194. {
  195. if($structure->subtype === "MIXED") {
  196. }
  197. while(list($index, $sub_structure) = each($structure->parts))
  198. {
  199. $prefix = null;
  200. if($part_number)
  201. {
  202. $prefix = $part_number . '.';
  203. }
  204. $data = $this->get_part($stream, $msg_number, $mime_type, $sub_structure, $prefix . ($index + 1));
  205. if($data)
  206. {
  207. return $data;
  208. }
  209. }
  210. }
  211. }
  212. return false;
  213. }
  214. /**
  215. * Get Total Number off Email In Mailbox
  216. * @return false or a number of unread mails
  217. */
  218. public function getTotalMails()
  219. {
  220. if(!$this->imap_stream) return false;
  221. return imap_num_msg($this->imap_stream);
  222. }
  223. function GetAttach($mid,$path = null) // Get Atteced File from Mail
  224. {
  225. if(!$this->imap_stream)
  226. return false;
  227. $struckture = imap_fetchstructure($this->imap_stream,$mid);
  228. $ar="";
  229. if($struckture->parts)
  230. {
  231. $data = array();
  232. foreach($struckture->parts as $key => $value)
  233. {
  234. $enc=$struckture->parts[$key]->encoding;
  235. if($struckture->parts[$key]->ifdparameters)
  236. {
  237. $name=$struckture->parts[$key]->dparameters[0]->value;
  238. $message = imap_fetchbody($this->imap_stream,$mid,$key+1);
  239. if ($enc == 0)
  240. $message = imap_8bit($message);
  241. if ($enc == 1)
  242. $message = imap_8bit ($message);
  243. if ($enc == 2)
  244. $message = imap_binary ($message);
  245. if ($enc == 3)
  246. $message = imap_base64 ($message);
  247. if ($enc == 4)
  248. $message = quoted_printable_decode($message);
  249. if ($enc == 5)
  250. $message = $message;
  251. // $fp=fopen($path.$name,"w");
  252. // fwrite($fp,$message);
  253. // fclose($fp);
  254. // $ar=$ar.$name.",";
  255. //$data[] = $message;
  256. }
  257. // Support for embedded attachments starts here
  258. // if($struckture->parts[$key]->parts)
  259. // {
  260. // foreach($struckture->parts[$key]->parts as $keyb => $valueb)
  261. // {
  262. // $enc=$struckture->parts[$key]->parts[$keyb]->encoding;
  263. // if($struckture->parts[$key]->parts[$keyb]->ifdparameters)
  264. // {
  265. // $name=$struckture->parts[$key]->parts[$keyb]->dparameters[0]->value;
  266. // $partnro = ($key+1).".".($keyb+1);
  267. // $message = imap_fetchbody($this->imap_stream,$mid,$partnro);
  268. // if ($enc == 0)
  269. // $message = imap_8bit($message);
  270. // if ($enc == 1)
  271. // $message = imap_8bit ($message);
  272. // if ($enc == 2)
  273. // $message = imap_binary ($message);
  274. // if ($enc == 3)
  275. // $message = imap_base64 ($message);
  276. // if ($enc == 4)
  277. // $message = quoted_printable_decode($message);
  278. // if ($enc == 5)
  279. // $message = $message;
  280. // $fp=fopen($path.$name,"w");
  281. // fwrite($fp,$message);
  282. // fclose($fp);
  283. // $ar=$ar.$name.",";
  284. // }
  285. // }
  286. // }
  287. }
  288. }
  289. return $data;
  290. // $ar=substr($ar,0,(strlen($ar)-1));
  291. // return $ar;
  292. }
  293. /**
  294. * gets mail body (text or html if available)
  295. * @param int $mail_number
  296. * @return string
  297. */
  298. function getBody($mail_number)
  299. {
  300. if(!$this->imap_stream)
  301. return false;
  302. $body = $this->get_part($this->imap_stream, $mail_number, "TEXT/HTML");
  303. if ($body == "")
  304. $body = $this->get_part($this->imap_stream, $mail_number, "TEXT/PLAIN");
  305. if ($body == "") {
  306. return "";
  307. }
  308. $body = $this->decodeMimeString($body);
  309. return $body;
  310. }
  311. /**
  312. * delete e-mail
  313. * @param int $mail_number
  314. * @return boolean
  315. */
  316. function deleteMail($mail_number)
  317. {
  318. if(!$this->imap_stream) return false;
  319. return imap_delete($this->imap_stream,$mail_number);
  320. }
  321. /**
  322. * closes connection to the mail server
  323. * @return boolean Returns TRUE on success or FALSE on failure.
  324. */
  325. public function close()
  326. {
  327. if(!$this->imap_stream) return true;
  328. return imap_close($this->imap_stream,CL_EXPUNGE);
  329. }
  330. /**
  331. * @author honza
  332. *
  333. * @param int $mail_id mail identificator
  334. * @return array of attachment parts
  335. */
  336. public function getMailAttachments($mail_id, $part_id = null, $data = false) {
  337. if(!$this->imap_stream)
  338. return false;
  339. $structure = imap_fetchstructure($this->imap_stream, $mail_id);
  340. if($structure->type == 0) {
  341. return;
  342. }
  343. $attachments = array();
  344. $parts = $structure->parts;
  345. $counter = 0;
  346. for($i = 0; $i < \count($structure->parts); $i++) {
  347. if($parts[$i]->ifdisposition === 0)
  348. continue;
  349. if($parts[$i]->disposition === "ATTACHMENT" && ($part_id === null || $i+1 == $part_id)) {
  350. $attachments[] = $this->makeAttachmentEntity($parts[$i], $mail_id, $i+1, $data);
  351. }
  352. }
  353. return $attachments;
  354. }
  355. public function getMailAttachmentData($mail_id, $part_id) {
  356. $attachments = $this->getMailAttachments($mail_id, $part_id, true);
  357. if(!empty($attachments)) {
  358. return $attachments[0];
  359. } else {
  360. return null;
  361. }
  362. }
  363. /**
  364. * @author honza
  365. *
  366. * @param attachment part (i.e. stdClass)
  367. */
  368. private function makeAttachmentEntity($part, $mail_id, $part_num, $getData = false) {
  369. $attEntity = new Attachment();
  370. $attEntity->setMail_id($mail_id);
  371. $attEntity->setBytes($part->bytes);
  372. $attEntity->setType($part->type);
  373. $attEntity->setPart_id($part_num);
  374. if($part->subtype)
  375. $attEntity->setSubtype($part->subtype);
  376. if($part->parameters)
  377. $attEntity->setName($this->getParameters($part->parameters, "NAME"));
  378. if($part->dparameters)
  379. $attEntity->setFileName($this->getParameters($part->dparameters, "FILENAME"));
  380. $mime_type = $this->get_mime_type($part);
  381. $attEntity->setMime_type($mime_type);
  382. $attEntity->setEncoding($part->encoding);
  383. if($getData === true)
  384. $attEntity->setData($this->getAttachData($mail_id, $part_num));
  385. return $attEntity;
  386. }
  387. /**
  388. * @author honza
  389. *
  390. * @param type $parameters array of parameters
  391. * @param type $pattern what attribute you want to find (e.g.)
  392. *
  393. * @return $value
  394. */
  395. private function getParameters($parameters, $pattern) {
  396. foreach($parameters as $parameter) {
  397. if($parameter->attribute === $pattern) {
  398. return $parameter->value;
  399. }
  400. }
  401. }
  402. private function getAttachData($mail_id, $partNum) {
  403. return imap_fetchbody($this->imap_stream, $mail_id, $partNum);
  404. }
  405. }