I was in a need for a class to get mails from a pop server to process them, so I’ve decided to leverage the Zend_Mail class, what I did was to create a wrapper around the Zend_Mail, to return all the messages from the server in a manageable way.
The first step was to put the needed Zend files in my library folder:
lib/Zend/Mail.php Mail |-- Exception.php |-- Message | |-- File.php | `-- Interface.php |-- Message.php |-- Part | |-- File.php | `-- Interface.php |-- Part.php |-- Protocol | |-- Abstract.php | |-- Exception.php | |-- Imap.php | |-- Pop3.php | |-- Smtp | | `-- Auth | | |-- Crammd5.php | | |-- Login.php | | `-- Plain.php | `-- Smtp.php |-- Storage | |-- Abstract.php | |-- Exception.php | |-- Folder | | |-- Interface.php | | |-- Maildir.php | | `-- Mbox.php | |-- Folder.php | |-- Imap.php | |-- Maildir.php | |-- Mbox.php | |-- Pop3.php | `-- Writable | |-- Interface.php | `-- Maildir.php |-- Storage.php `-- Transport |-- Abstract.php |-- Exception.php |-- Sendmail.php `-- Smtp.php
Then I started writing my class:
< ?php set_include_path('lib' . PATH_SEPARATOR . get_include_path()); include_once 'Zend/Mail.php'; include_once 'Zend/Mail/Storage/Pop3.php'; include_once 'Zend/Mail/Transport/Smtp.php'; include_once 'Zend/Mime/Part.php'; /** * Class to get mails from a server */ class mailFetcher { private $_emailHost = 'pop.server.com'; private $_emailUser = '[email protected]'; private $_emailPass = 'password'; /** * Zend_Mail_Storage */ private $_mail; /** * Inbox wrapper */ private $_inbox = array(); /** * on class instantiation we fire connect * to the pop server and start fetching the mails */ public function __construct() { try { $this->_mail = new Zend_Mail_Storage_Pop3(array( 'host' => $this->_emailHost, 'user' => $this->_emailUser, 'password' => $this->_emailPass)); } catch (Exception $e) { echo 'Mail Retrieval Failed...' . PHP_EOL; die(); } $this->processMail(); } private function _contentDecoder($encoding, $content) { switch ($encoding) { case 'quoted-printable': $result = quoted_printable_decode($content); break; case 'base64': $result = base64_decode($content); break; default: $result = $content; break; } return $result; } /** * This is where everything is done */ public function processMail() { if ($this->_mail instanceof Zend_Mail_Storage_Pop3 && $this->_mail->countMessages() > 0) { $messageNum = 0; foreach ($this->_mail as $message) { $messageNum++; $rawMail = $this->_mail->getRawHeader($messageNum) . $this->_mail->getRawContent($messageNum); $received = $message->received; $date = date('Y-m-d H:i:s', strtotime($message->date)); $messageId = $message->headerExists('message-id') ? $message->getHeader('message-id') : null; //remove <> from message id $messageId = (preg_match('|< (.*?)>|', $messageId, $regs)) ? $regs[1] : $messageId; $inReplyTo = $message->headerExists('in-reply-to') ? $message->getHeader('in-reply-to') : null; //remove <> from in-reply-to $inReplyTo = (preg_match('|< (.*?)>|', $inReplyTo, $regs)) ? $regs[1] : $inReplyTo; $references = $message->headerExists('References') ? $message->getHeader('References') : null; //remove <> from references $references = (preg_match('|< (.*?)>|', $references, $regs)) ? $regs[1] : $references; $from = $message->from; $subject = $message->subject; $to = $message->to; $plainContent = null; $htmlContent = null; $attachments = array(); /** * Check if the message has multiple parts */ if ($message->isMultipart()) { /** * We have a multipart message * lets extract the plain content, * html content, and attachments */ foreach (new RecursiveIteratorIterator($message) as $part) { try { switch (strtok($part->contentType, ';')) { case 'text/plain': $plainContent = $this->_contentDecoder($part->getHeader('content-transfer-encoding'), $part->getContent()); break; case 'text/html': $htmlContent = $this->_contentDecoder($part->getHeader('content-transfer-encoding'), $part->getContent()); break; default: //attachment handle $type = strtok($part->contentType, ';'); $fileName = $part->getHeader('content-description'); $attachment = $this->_contentDecoder($part->getHeader('content-transfer-encoding'), $part->getContent()); $attachments[] = array( 'file_name' => $fileName, 'type' => $type, 'content' => $attachment); break; } } catch (Zend_Mail_Exception $e) { echo "$e \n"; } } } else { $plainContent = $message->getContent(); } $this->_inbox[] = array('messageNumber' => $messageNum, 'rawMail' => $rawMail, 'received' => $received, 'date' => $date, 'messageId' => $messageId, 'inReplyTo' => $inReplyTo, 'references' => $references, 'from' => $from, 'subject' => $subject, 'to' => $to, 'plainContent' => $plainContent, 'htmlContent' => $htmlContent, 'attachments' => $attachments); } } else { $this->_inbox = false; } } public function getInbox() { return $this->_inbox; } }
My fetch class does everything on instantiation, and it will have all the mails retreived, so for example if I need to get all messages I can do this:
< ?php include_once 'mailFetcher.php'; $inbox = new mailFetcher(); print_r($inbox->getInbox());
And this would be the result:
Array ( [0] => Array ( [messageNumber] => 1 [rawMail] => Received: from gate55.gate.iad.mailserver.com (11.1.111.1) by IAD2HUB01.mex02.mailserver.com (111.11.11.65) with Microsoft SMTP Server (TLS) id 8.2.247.2; Wed, 9 Jun 2010 17:56:16 -0400 Received: from mail-yw0-f186.google.com (mail-yw0-f186.google.com [111.11.111.186]) by gate55.gate.iad.mailserver.com (SMTP Server) with ESMTP id B1F6E31D0171 for <asdfasdf @ivanvillareal.com>; Wed, 9 Jun 2010 17:56:15 -0400 (EDT) Received: by ywh16 with SMTP id 16so5309053ywh.32 for </asdfasdf><asdfasdf @ivanvillareal.com>; Wed, 09 Jun 2010 14:56:15 -0700 (PDT) Received: by 10.111.111.111 with SMTP id jz1mr465966qcb.170.1276120573865; Wed, 09 Jun 2010 14:56:13 -0700 (PDT) Received: by 11.111.111.11 with HTTP; Wed, 9 Jun 2010 14:56:13 -0700 (PDT) From: Ivan Villareal <ivaano @gmail.com> To: "[email protected]" <asdfasdf @ivanvillareal.com> Date: Wed, 9 Jun 2010 17:56:13 -0400 Subject: attachment test Thread-Topic: attachment test Thread-Index: AcsIHpXuE+vWJJMfTGyqikgD2kYkng== Message-ID: <aanlktingkmpbkefog5kxxoq8wrib7tj1pt1rsy -[email protected]> Accept-Language: en-US Content-Language: en-US X-MS-Exchange-Organization-AuthAs: Anonymous X-MS-Exchange-Organization-AuthSource: IAD2HUB01.mex02.mailserver.com X-MS-Has-Attach: yes X-MS-TNEF-Correlator: x-virus-scanned: OK, catchall x-originating-ip: [111.11.111.186] dkim-signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:mime-version:received:received:date:message-id :subject:from:to:content-type; bh=IvMOHmKRabcJ2PrUHPHB/NbNpgQubvvgGprC6gtDY9E=; b=cA5Pjycedt9Pylic7CTk4HCF6HXV9eEFpr086KwcMepGKJEv4DWU6d4iFt4Gp7R42V +4rVmrmwj2j9yj1vbEUqVMI6/m+Kkwt1r+MAtN/0qZsvEaVBBbbjTBxFLO9cQ7xlaSSm eGTHv9mR0qCcBZGLOVFeWUNiYDkhY2F0eDUbU= domainkey-signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=mime-version:date:message-id:subject:from:to:content-type; b=VKdlRSfBz/Swij0xE0c7Su8TOwcc2YGmw0K8dvVxoS9TJf0p8nIqtR6nQtmKqabSu4 g2ALFFHXuVOhGpP+JdvI3wQJ1k9N5EZhcWtSRECrikOlLnaDA8/4z3SYckY6hs7Q+KIe qG0IbY+QkuZh7yymcyAN5omTaFDFT2GIPs+1c= x-orig-to: [email protected] Content-Type: multipart/mixed; boundary="_004_AANLkTingkMPbKeFog5kxXoq8WRib7tJ1pT1Rsy1ug1mailgmailcom_" MIME-Version: 1.0 --_004_AANLkTingkMPbKeFog5kxXoq8WRib7tJ1pT1Rsy1ug1mailgmailcom_ Content-Type: multipart/alternative; boundary="_000_AANLkTingkMPbKeFog5kxXoq8WRib7tJ1pT1Rsy1ug1mailgmailcom_" --_000_AANLkTingkMPbKeFog5kxXoq8WRib7tJ1pT1Rsy1ug1mailgmailcom_ Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: base64 amhnamhnamhnDQo= --_000_AANLkTingkMPbKeFog5kxXoq8WRib7tJ1pT1Rsy1ug1mailgmailcom_ Content-Type: text/html; charset="utf-8" Content-Transfer-Encoding: base64 amhnamhnamhnDQo= --_000_AANLkTingkMPbKeFog5kxXoq8WRib7tJ1pT1Rsy1ug1mailgmailcom_-- --_004_AANLkTingkMPbKeFog5kxXoq8WRib7tJ1pT1Rsy1ug1mailgmailcom_ Content-Type: image/jpeg; name="2010-05-28-112655.jpg" Content-Description: 2010-05-28-112655.jpg Content-Disposition: attachment; filename="2010-05-28-112655.jpg"; size=15004; creation-date="Wed, 09 Jun 2010 17:56:16 GMT"; modification-date="Wed, 09 Jun 2010 17:56:16 GMT" Content-Transfer-Encoding: base64 /9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0a gq4UlFJmmKwtHakzS0DsMNFLikIxQAUmKKM0AFLSUtABRRRQAlFGeaKACiikouAtGaKPrQAmaKDS 4oASgClxRQKwUUUlAxaKKM0AFBNFGM0AGalHzIKiIp6HgigQuKKKKQyZDlaJAcU2I09+VP0qWSRK R0zTGXBpuec1IDvX3qihqNhhV5WG0Vn9DUocgUMTJpyCpIqsKezZXmoqENDqQ0dqBmmMBS0UmKAF oFJS0AJ3oIpQKQk0AAp4JxTBTxQwYE0oFNNOU8UhCkDGKaRin0EZoEiLIpcUuzuKMUyrje9FKQet J2oGf//Z --_004_AANLkTingkMPbKeFog5kxXoq8WRib7tJ1pT1Rsy1ug1mailgmailcom_-- [received] => from gate55.gate.iad.mailserver.com (11.1.111.1) by IAD2HUB01.mex02.mailserver.com (111.11.11.15) with Microsoft SMTP Server (TLS) id 1.1.147.2; Wed, 9 Jun 2010 17:56:16 -0400 from mail-yw0-f186.google.com (mail-yw0-f186.google.com [209.85.211.186]) by gate55.gate.iad.mailserver.com (SMTP Server) with ESMTP id B1F6E31D0171 for <asdfasdf @ivanvillareal.com>; Wed, 9 Jun 2010 17:56:15 -0400 (EDT) by ywh16 with SMTP id 16so5309053ywh.32 for </asdfasdf><asdfasdf @ivanvillareal.com>; Wed, 09 Jun 2010 14:56:15 -0700 (PDT) by 10.229.233.193 with SMTP id jz1mr465966qcb.170.1276120573865; Wed, 09 Jun 2010 14:56:13 -0700 (PDT) by 10.229.192.82 with HTTP; Wed, 9 Jun 2010 14:56:13 -0700 (PDT) [date] => 2010-06-09 14:56:13 [messageId] => [email protected] [inReplyTo] => [references] => [from] => Ivan Villareal <ivaano @gmail.com> [subject] => attachment test [to] => "[email protected]" <asdfasdf @ivanvillareal.com> [plainContent] => jhgjhgjhg [htmlContent] => jhgjhgjhg [attachments] => Array ( [0] => Array ( [file_name] => 2010-05-28-112655.jpg [type] => image/jpeg ) ) ) )</asdfasdf></ivaano></asdfasdf></aanlktingkmpbkefog5kxxoq8wrib7tj1pt1rsy></asdfasdf></ivaano></asdfasdf>
From this point I can iterate the inbox easily saving the email results or applying other logic to it,