Skip to main content

eZ components "Mail" to save the day

A few days ago I was asked to develop a simple script for a solidarity campaign. The idea is that people send their photos as attachements to some email. The script would download all images attached and insert a record for that in the database.
I got introduced to eZ components during my last visit to Norway to attend the eZ systems conference. I decided to give it a shot, and oh boy it's just amazing, probably the cleanest and simplest API ever.
I managed to find the package "Mail":
The components allows you construct Mail messages conforming to the RFCs. It has support for attachments, multipart messages and HTML mail. It also interfaces with SMTP to send the e-mail. Reading and parsing mail messages comes in version 1.1.

The package is well documented and includes many examples. Here's the script I ended up writing (edited version):

[coolcode lang="php"]
< ?php
define( 'PHOTOS_DIR', 'email_photos/' );
define( 'FILE_PARSED_MAILS', '.fpm' );
require_once 'Base/src/base.php';
function __autoload( $className )
{
ezcBase::autoload( $className );
}
//get the list of emails that we alread processed
$parsedEmailsIds = array();
$parsedEmailsIds = @unserialize( file_get_contents(FILE_PARSED_MAILS) );
if( 'array' != gettype($parsedEmailsIds) ){
$parsedEmailsIds = array();
}
$pop3 = new ezcMailPop3Transport( 'mail.example.org' );
$pop3->authenticate( 'username', 'password' );
//get the list of emails from the server
$severEmailsIds = $pop3->listUniqueIdentifiers();
$emailsToFetch = array_diff($severEmailsIds, $parsedEmailsIds);
if( !count($emailsToFetch) ){
//no emails to get!
exit;
}
$set = $pop3->fetchAll(false, $emailsToFetch );
$parser = new ezcMailParser();
$parser->setTmpDir( 'tmp/' );
$mails = $parser->parseMail( $set );
foreach ( $mails as $mail )
{
//Get email parts
foreach( $mail->body->getParts() as $part ){
if( get_class($part) == 'ezcMailFile' ){
//get the destination file name after some cleanups
$fileName = nameToSafe( basename($part->fileName) );
//the new destintation filename, this function makes sure we get a unique file name everytime
$destFileName = PHOTOS_DIR . nameToSeq(PHOTOS_DIR,$fileName);
rename( $part->fileName, $destFileName );
}
//after we're done, we need to update the file that stores the list of parsed emails
file_put_contents( FILE_PARSED_MAILS, serialize( $severEmailsIds ) );
?>
[/coolcode]
I'm sure there's a better way to get the new emails only, probably with var_export()
Note: The only problem I faced, which is VERY strange, is the ability to fetch a single email or list of emails. Surprisingly, the API didn't provide such feature. I did an ugly hack to "Mail/transports/pop3/pop3_transport.php" to function fetchAll(), I should have created another function, but I was in a hurry. Here's the modified version:
[coolcode lang="php"]
/**
* @throws ezcMailTransportException if the mail could not be retrieved.
* @param bool $deleteFromServer
* @param array $messages
* @return ezcMailParserSet
*/
public function fetchAll( $deleteFromServer = false, $messages = null )
{
if( !isset($messages) ){
$message = $this->listMessages();
}
return new ezcMailPop3Set( $this->connection, array_keys( $messages ), $deleteFromServer );
}
[/coolcode]

[tags] package mail, mail body, solidarity campaign, mail messages, multipart messages, ez systems, attachements, edited version, fpm, rfcs, e mail, parsing, smtp, array, few days, attachments, email, norway, fi, images [/tags]

Comments

  1. You can actually fetch a single email, but it seems that it is currently only implemented for the mbox transport. However, we are currently working on adding this method to the pop transport as well, and to add a new function to get a set of mail messages (similar to limit/offset).

    ReplyDelete
  2. Jad Madi's Blog: eZ components "Mail" to save the day...
    ...

    ReplyDelete
  3. [...] From browsing around the source (having been reminded by Jad Madi’s blog to take a look), the good news is it looks like eZ systems have this problem well solved. The ezcMail class, and related classes default to (assume) ASCII but you can explicitly tell it to use UTF-8 (note iconv is required) for subject, recipient, sender and body. In fact it’s a very impressive mail library all round, handling parsing as well as generating, multipart messages and all that. [...]

    ReplyDelete
  4. [...] From browsing around the source (having been reminded by Jad Madi’s blog to take a look), the good news is it looks like eZ systems have this problem well solved. The ezcMail class, and related classes default to (assume) ASCII but you can explicitly tell it to use UTF-8 (note iconv is required) for subject, recipient, sender and body. In fact it’s a very impressive mail library all round, handling parsing as well as generating, multipart messages and all that. [...]

    ReplyDelete
  5. Been trying to get it to work for over two hours with no success. Not impressed at all!

    ReplyDelete
  6. Been trying to get it to work for over two hours with no success. Not impressed at all!

    ReplyDelete

Post a Comment

Popular posts from this blog

اهم التطورات العلمية في العام ٢٠١٩

القضاء: لا دليل على أن مقتحمي الكونغرس خططوا لقتل مشرعين

أكد محققو وزارة العدل الأمريكية أنهم لم يجدوا حتى الآن أي دليل على أن أنصار دونالد ترامب الذين هاجموا مبنى الكونغرس الأسبوع الماضي خططوا لاحتجاز مسؤولين منتخبين وقتلهم. يأتي ذلك في الوقت الذي أُوقفت فيه الشرطة، الجمعة، رجلا مسلّحا في واشنطن خلال محاولته عبور إحدى نقاط التفتيش في محيط مبنى الكونغرس حيث ستقام الأربعاء مراسم تنصيب جو بايدن. في ذات الوقت أفادت شبكة NBC الأمريكية، بأن مكتب التحقيقات الفيدرالي يحقق في إمكانية تمويل حكومات أو جماعات اقتحام مبنى الكونغرس. وقالت مصادر للشبكة: "المكتب يحقق في مدفوعات "بيتكوين" بقيمة 500 ألف دولار، يبدو أنه تم تحويلها من قبل مواطن فرنسي، لشخصيات ومجموعات رئيسية يمينية قبل اندلاع أعمال الشغب". وفي جلسة استماع في محكمة أريزونا بشأن اعتقال أحد مثيري الشغب جاكوب تشانسلي الذي يؤمن بنظرية المؤامرة ومن أتباع الحركة اليمينية المتطرفة "كيو-آنون"، تراجع المدعون الفيدراليون عن اتهامات سابقة بأن أنصار ترامب كانوا يخططون "لاحتجاز مسؤولين منتخبين وقتلهم" في هجوم السادس من كانون الثاني/ يناير في واشنطن. ع
Dear Microsoft : It's over. Our relationship just hasn't been working for a while, and now, this is it. I'm leaving you for another Operating system. I know this isn't a good time--you're down with yet another virus. I do hope you feel better soon--really, I do--but I, too, have to move on with my life. Fact is, in the entire time I've known you, you seem to always have a virus or an occasional worm. You should really see a doctor. That said, I just can't continue with this relationship any longer. I know you say you'll fix things, that next time it'll go better--but that's what you said the last time--and the time before that. Each time I believed you. Well, not any longer. You cheater! The truth is there's nothing more you can say to make things better. I know about your secret marriage to patent. You say you two are not seeing each other anymore, but I just don't believe it. You say you can live without patent, and I've heard that