В рамках корпоративной ERP-системы (упоминал в своей прошлой записи) разрабатывается web-mail-клиент (о как). Долго думал, использовать Pop3 или же imap. Все-таки выбрал imap, посмотрел в интернетах на наличие готовых решений. Нашел, но немного не того, пришлось пилить. Процесс, конечно еще продолжается, но костяк более-менее сделал (Скажу сразу, что дополнял класс. Он работает, но ряд вещей стоит все же переписать:
подключение и юзание:
да, кстати,есть небольшая бага: в некоторых случаях название атачей будет типа =?UTF_8?B?..... лечится просто :
/* * Класс предназначен для считывания данных(писем) почты посредством работы (IMAP подключени к серверу) */ class ImapCheck { private $mbox; private $htmlmsg; private $plainmsg; private $charset; private $attachments = array(); private $unread; private $hcharset; private $filescount =0; /* public function __get($name) { if ($name=='mail') return $this->unread; else return null; }*/ public function getmail() { return $this->unread; } /** * Конструктор * @param string $host хост * @param string $login аккаунт ящика * @param string $pwd пароль * @param array $options * [letterID] = null|int - если известен ид письма * [search] = * ALL - return all messages matching the rest of the criteria ANSWERED - match messages with the \\ANSWERED flag set BCC "string" - match messages with "string" in the Bcc: field BEFORE "date" - match messages with Date: before "date" BODY "string" - match messages with "string" in the body of the message CC "string" - match messages with "string" in the Cc: field DELETED - match deleted messages FLAGGED - match messages with the \\FLAGGED (sometimes referred to as Important or Urgent) flag set FROM "string" - match messages with "string" in the From: field KEYWORD "string" - match messages with "string" as a keyword NEW - match new messages OLD - match old messages ON "date" - match messages with Date: matching "date" RECENT - match messages with the \\RECENT flag set SEEN - match messages that have been read (the \\SEEN flag is set) SINCE "date" - match messages with Date: after "date" SUBJECT "string" - match messages with "string" in the Subject: TEXT "string" - match messages with text "string" TO "string" - match messages with "string" in the To: UNANSWERED - match messages that have not been answered UNDELETED - match messages that are not deleted UNFLAGGED - match messages that are not flagged UNKEYWORD "string" - match messages that do not have the keyword "string" UNSEEN - match messages which have not been read yet * флаги для поиска */ public function ImapCheck($host, $login, $pwd, $options = array('search'=>'ALL')) { $messages=array(); $folder="INBOX"; //$folder="[Gmail]/&BCEEPwQwBDw-"; // если вам захочется почитать спам на гугломыле. $this->mbox = imap_open ("{$host}$folder", $login,$pwd) or die(imap_last_error());//OP_HALFOPEN if(isset($options["search"])) { if(!isset($options["letterID"]) || $options["letterID"] == NULL) { $arr = imap_search ($this->mbox, $options["search"]); if ($arr !== false) { foreach ($arr as $i) $messages[]=$this->getLEtter($i); $this->unread=$messages; unset($messages); } else {$this->unread=false;} } else $this->unread[$options["letterID"]]=$this->getLEtter($options["letterID"]); } else die("parametr options->search are empty!"); } /** * заголовок от письма * @param $num номер письма в ящике * @return array */ public function getHeaderInfo($num) { $headerArr = imap_headerinfo ( $this->mbox, $num); $elements = imap_mime_header_decode($headerArr->subject); $subj = ""; for ($p = 0; $p < count($elements); $p++) { if($elements[$p]->charset !="default" && strtolower($elements[$p]->charset) !="utf-8") { $subj .= iconv($elements[$p]->charset, 'UTF-8', $elements[$p]->text); $this->charset = $elements[$p]->charset; $this->hcharset = $elements[$p]->charset; } else if($elements[$p]->charset =="default") { $subj.= iconv('KOI8-R','UTF-8', $elements[$p]->text); $this->charset = 'KOI8-R'; $this->hcharset = 'KOI8-R'; } else { $subj.=$elements[$p]->text; $this->charset = 'UTF-8'; $this->hcharset = 'UTF-8'; } } if(!isset($headerArr->sender[0]->personal)) $headerArr->sender[0]->personal = "unknown"; return array( 'from'=> $headerArr->sender[0]->mailbox . "@" . $headerArr->sender[0]->host, 'to'=> $headerArr->to[0]->mailbox . "@" . $headerArr->to[0]->host, 'name'=> $this->decode($headerArr->sender[0]->personal) , 'subject'=>$subj, 'Date'=>strtotime($headerArr->Date) ); } /** * чтение письма по номеру * @param $num номер * @return array */ public function getLetter($num) { $return = $this->getHeaderInfo($num); $this->getmsg($num); //читаем тело письма (сообщение) //imap_setflag_full($this->mbox, $i, "\\Seen"); //прочли письмо, поставили флаг, что прочли $return["charset"] = $this->charset; $return["plain"] = $this->plainmsg; $return["html"] = $this->htmlmsg; $return["attach"] = $this->attachments; $return["letterID"] = $num; return $return; } private function decode($enc) { $parts = imap_mime_header_decode($enc); $str=''; for ($p=0; $pcharset; $part = $parts[$p]->text; if ($ch!=='default') $str.=mb_convert_encoding($part,'UTF-8',$ch); elseif ($ch=='default') $str.=mb_convert_encoding($part,'UTF-8','KOI8-R'); else $str.=$part; } return $str; } private function getmsg($mid) { $this->htmlmsg = $this->plainmsg = $this->charset = ''; $this->attachments = array(); $s = imap_fetchstructure($this->mbox,$mid); if (!isset($s->parts)) $this->getpart($mid,$s,0); else { foreach ($s->parts as $partno0=>$p) $this->getpart($mid,$p,$partno0+1); } } private function getpart($mid,$p,$partno) { $data = ($partno) ? imap_fetchbody($this->mbox,$mid,$partno): imap_body($this->mbox,$mid); if ($p->encoding==4) $data = quoted_printable_decode($data); elseif ($p->encoding==3) $data = base64_decode($data); $params = array(); if (isset($p->parameters)) foreach ($p->parameters as $x) $params[ strtolower( $x->attribute ) ] = $x->value; if (isset($p->dparameters)) foreach ($p->dparameters as $x) $params[ strtolower( $x->attribute ) ] = $x->value; if (isset($params['filename']) || isset($params['name'])) { $filename = (isset($params['filename']))? $params['filename'] : $params['name']; if(isset($this->attachments[$filename])) //если уже есть в атачменте такой файл, делаем "версионность" { $this->filescount ++; $filename = $this->filescount."_".$filename; } $this->attachments[$filename] = $data; } elseif ($p->type==0 && isset($data)) { if (strtolower($p->subtype)=='plain') { $this->plainmsg .= trim($this->ConvBody($data)) ."\n\n"; } else $this->htmlmsg .= $this->ConvBody($data) ."
"; if(isset($params['charset'])) $this->charset = $params['charset']; } elseif ($p->type==2 && isset($data)) { $this->plainmsg .= trim($this->ConvBody($data)) ."\n\n"; } if (isset($p->parts)) { foreach ($p->parts as $partno0=>$p2) $this->getpart($mid,$p2,$partno.'.'.($partno0+1)); } } private function ConvBody($text) { if(!empty($this->hcharset) && $this->hcharset !='UTF-8') { $text = iconv($this->hcharset, 'UTF-8', $text); } return $text; } /** * Закрыть имап подключение */ public function close() { imap_close($this->mbox); } } //TODO: отловить момент, когда делают рассылку и данный пользователь так же учавствует в ней, выдает адрес, перввый из списка [to]
подключение и юзание:
require "inc/imap.php"; $options = array('search'=>'SINCE "'.date("j F Y",strtotime("-1 DAY")).'"');//тип поиска сообщений на почте - собираем сообщения со вчера по седня :) $rm = new ImapCheck("{server.ru/imap}","mail@server.ru","password",$options); $mail_list = $rm->getmail(); //получили письма $rm->close();выплюнет массив с письмами примерно так: [from] =>откуда [to] => кому [name] => имя приславшего [subject] => название [Date] => дата, письма [charset] => кодировка [plain] => если обычный текст [html] => если хтмл-код [letterID] => id письма на сервере (не постоянно! по факту это просто количественный номер) [attach] => Array ( [название_изображения] => бинарное содержание(то есть можно обычным fput воткнуть куда надо) )
iconv_mime_decode("название файла",0, "кодировка")надеюсь, кому-то помог.
Комментариев нет:
Отправить комментарий